home *** CD-ROM | disk | FTP | other *** search
/ A.C.E. 2 / ACE CD 2.iso / FILES / DOCS / AMOSDOC.LHA / AmosPart3.doc < prev    next >
Text File  |  1994-11-27  |  130KB  |  3,354 lines

  1. 11: HARDWARE SPRITES
  2. One of the biggest attractions of the Commodore Amiga is its ability to
  3. produce high quality games which rivial those found on genuine arcade
  4. machines. This can be amply demonstrated by terrific programs such as
  5. Battle Squadron and Eliminator.
  6.  
  7.   Now, for the first time, all these amazing features are at your
  8. fingertips! AMOS Basic provides you with complete control over the
  9. Amiga's hardware and software sprites. These sprites can be
  10. effortlessly manoeuvred with the built-in AMAL animation language, so
  11. you don't have to be a machine code wizard in order to create your own
  12. stunning arcade games.
  13.  
  14.   Hardware sprites are searate images which can be automatically
  15. overlayed on the Amiga's screen. The classic example of a hardware
  16. sprite is the mouse pointer. This is completely independent of the
  17. screen, and works equally well in all the Amiga's graphics modes.
  18.  
  19.   Since sprites don't interfere with the screen background, they are
  20. perfect for the moving objects required by an arcade game. Not only are
  21. they blindingly fast, but they also take up very little memory. So when
  22. you're writing an arcade game, hardware sprites should always be at the
  23. top of your list.
  24.  
  25.   Each sprite is 16 pixews wise and up to 255 pixels high. The Amiga's
  26. hardware supports a maximum of eight three-colour sprites or four
  27. fifteen-colour sprites. Colour number zero is transparent - that's the
  28. reason for the odd colour ranges.
  29.  
  30.   At first glance, these features don't seem particulary impressive.
  31. But there are a couple of useful tricks which can increase both the
  32. numbers and sizes of these sprites beyond recognition.
  33.  
  34.   One solution is to take each hardware sprite and split it into a
  35. number of horizontal segments. These segments can be independently
  36. positioned, allowing you to apparently display dozens of sprites on the
  37. screen at once. Similarly, the width restriction can be exceeded by
  38. building an object out of several individual sprites. Using this
  39. technique it's easy to generate objects up to 128 pixels wide.
  40.  
  41.   Until recently the only way to exploit these techniques was to delve
  42. into the mysterious wolrd of 68000 assembler language. So you'll be
  43. delighted to discover that AMOS Basic manages the entire process
  44. automatically! Once you've designed your sprites with the AMOS sprite
  45. editor, you can effortlessly manipulate them with just a single Basic
  46. instruction.
  47.  
  48. The sprite commands
  49. ===================
  50. Remember to have a sprite bank loaded into memory when trying out the
  51. various commands in this chapter. We advise you use the file
  52. SPRITES.ABK from the AMOS data disc.
  53.  
  54.  
  55.  
  56.            SPRITE (display a hardware sprite on the screen)
  57.  
  58. SPRITE n,x,y,i
  59.  
  60. The SPRITE command displays a hardware sprite on the screen at
  61. coordinates x,y using image number i.
  62.  
  63.   n is the identification number of the sprite and can range from 0 to
  64. 63. Each sprite can be associated with a separate image from the sprite
  65. bank, so the same image can be used for several sprites.
  66.  
  67.   x and y hold the position of the sprite using special hardware           146
  68. coordinates. All measurements are taken from the *hot spot* of your
  69. images. This serves as a sort of 'handle' on the sprite and is used as
  70. a reference point for the coordinates. Normally the hot spot is set to
  71. the top left hand corner of an image. However it can be changed within
  72. your program using the HOT SPOT command.
  73.  
  74.   Hardware coordinates are independent of the screen mode and
  75. effectively start from (-129,-45) on the default screen. AMOS provides
  76. you with several built-in functions for conversions between hardware
  77. coordinates and the easier to use screen coordinates. See the X HARD,
  78. Y HARD, X SCREEN and Y SCREEN functions for more details.
  79.  
  80.   i is the number of a particular image stored in the sprite bank. This
  81. bank can be created using the AMOS sprite editor, and is automatically
  82. saved along with your Basic program. It can also be loaded directly
  83. with the LOAD instruction. In addition you can use the GET SPRITE
  84. command to grab an image straight off the current screen.
  85.  
  86.   Any of these parameters x,y and i may be optionally omitted, but the
  87. appropriate commas must be included. For example:
  88.  
  89.         Load "AMOS_DATA:Sprites/Octopus.abk"
  90.         Sprite 8,200,100,1
  91.         Sprite 8,,150,1
  92.         Sprite 8,300,,
  93.  
  94. For a demonstration of sprites in action, load EXAMPLE 11.1 from the
  95. MANUAL folder on the AMOS data disc.
  96.  
  97.  
  98. Computed sprites
  99. ================
  100. Although the Amiga only provides you with eight actual sprites, it's
  101. possible to use them to display up to 64 different objects on the
  102. screen at once. These objects are known as -computed sprites- and are
  103. managed antirely by AMOS Basic. Computed sprites can be assigned by
  104. calling the SPRITE command with a number greater than 7. For example,
  105.  
  106.         Load "AMOS_DATA:Sprites/Octopus.abk"
  107.         Sprite 8,200,100,1
  108.  
  109. The size of a computed sprite is taken directly from the image data,
  110. and can vary between 16 and 128 pixels wide, and from 1 to 255 pixels
  111. high.
  112.  
  113.   Before you can make full use of these sprites you need to understand
  114. some of the principles behind them. Each hardware sprite consists of a
  115. thin narrow strip 16 pixels wide and 256 pixels deep. Depending on the
  116. number of colours, you can have either eight or four of these strips on
  117. the screen at a time.
  118.  
  119.   It should be obvious that most of the area inside these sprites is       147
  120. effectively wasted. That's because few programs need sprites which are
  121. taller than about 40 or 64 pixels. However there is a simple trick
  122. which enables us to borrow this space to generate dozens of extra
  123. objects on the screen. Look at the picture AMOS1.PIC (included in this
  124. manual file packet) which contains the letters A,M,O and S.
  125.  
  126.            < picture   AMOS1.PIC >
  127.  
  128. This sprite can be split into four horizontal segments each enclosing a
  129. single letter. The Amiga's hardware allows each section to be freely
  130. positioned anywhere on the current line, making a total of four
  131. computed sprites. Here's a diagram which illustrates this process.
  132.  
  133.            < picture   AMOS2.PIC >                                         148
  134.  
  135. As you can see, a computed sprite is really just a small part of a
  136. hardware sprite displayed at a different horizontal screen position.
  137. Notice the line between each object. This is an unavoidable side effect
  138. of the repositioning process, and is generated by the Amiga's hardware.
  139.  
  140.   Due to the way computed sprites are produced, there are a couple of
  141. restrictions to their use. Firstly, you can't have more than 8 computed
  142. sprites on a single line. In practice the system is complicated by the
  143. need to produce sprites which are larger than the 16 pixel maximum.
  144. AMOS generates these objects by automatically positioning several
  145. computed sprites side by side. This can be seen from the diagram below:
  146.  
  147.            < picture   AMOS3.PIC >
  148.  
  149. The maximum of eight hardware sprites therefore imposes a strict limit
  150. to the number of such objects you can display on a horizontal line. The
  151. total width of the objects must not exceed:
  152.  
  153.         16*8=128 pixels for three-colour sprites                           149
  154.         16*4=64  pixels for fifteen-colour sprites
  155.  
  156. If you attempt to ignore limitation, you won't get an error message,
  157. but your computer sprite will not be displayed on the screen. So it's
  158. vital to ensure that the above restriction is never broken. This can be
  159. achieved using the following procedure:
  160.  
  161.   Add together the widths of all your computed sprites, multiplying the
  162. dimensios of any fifteen-colour sprites by two. If the total is
  163. greater than 128, you'll need to space your sprites on the screen so
  164. that their combined width lies below this value. Take particular care
  165. if you are animating your sprites with AMAL as certain combinations
  166. will only come to light after you've experimented with the sequence for
  167. some time. These problems will be manifested by the random
  168. disappearance of one or more sprites on the screen.
  169.  
  170.   If the worst comes to the worst, you'll need to substitute some of
  171. your larger sprites with Blitter Objects. This will increase the
  172. overall size of your program significantly, but it should have a
  173. negligible effect on the final quality of your game.
  174.  
  175.   These restrictions are not confined to AMOS Basic of course. They
  176. apply equally well to all games on the Amiga, even if they're written
  177. entirely in machine code! So there's nothing stopping you from
  178. producing your own Xenon II clone using exactly the same tehcniques.
  179.  
  180.   Note that, normally, hardware sprite number zero is allocated to the
  181. mouse cursor. You can release this sprite with a simple call to the
  182. HIDE command. See EXAMPLE 11.2.
  183.  
  184.  
  185. Creating an individual hardware sprite
  186. ======================================
  187. The only real problem with computed sprites is that you never know
  188. precisely which hardware sprite is going to be used in a particular
  189. object. Normally the hardware sprites used in an object will change
  190. whenever the object is moved. Occasionally this can be inconvenient,
  191. especially when you are animating objects such as missiles which need
  192. to remain visible in a wide range of possible sprite combinations.
  193.  
  194.   In these circumstances it's useful to be able to allocate a hardware
  195. sprite directly. Individual hardware sprites can be assigned using the
  196. SPRITE instruction with an identification number between 0 and 7.
  197. Example:
  198.  
  199.         Sprite 1,100,100,2
  200.  
  201. This loads a hardware sprite number 1 with image number 2. N now
  202. corresponds to the number of a single hardware sprite, and can range
  203. between 0 and 7. If your image is larger than sixteen pixels wide, AMOS
  204. will automatically grab the required sprites in consecutive order
  205. starting from the sprite you have chosen. For example:
  206.  
  207.         Sprite 2,200,100,1
  208.  
  209. Supposing image number 1 contained a 32-bit image with three colours.
  210. This command would allocate hardware spries 2 and 3 to the image.
  211. Nothing would happen if you were now to attempt to display hardware
  212. sprite 3 with a command like SPRITE 3,150,100,1  because this sprite
  213. has already been used. You would only have access to sprites 0,1,4,5,6
  214. and 7, and the maximum numbers and sizes of your computed sprites would
  215. be reduced accordingly.
  216.  
  217.   Each 15-colour sprite is implemented using a pair of two three-colour    150
  218. sprites. However, it's not possible to combinea ny two sprites in this
  219. way. Only the combinations 0/1,2/3,4/5,6/7 are allowed. One side effect
  220. of this, is that you should always assign your hardware sprites using
  221. even sprite numbers. Otherwise, AMOS will start your sprite from the
  222. next group of two, effectively wasting the first sprite.
  223.  
  224.   Also note that if you try to create a large fifteen-colour sprite
  225. with this system, you could easily use up all the available sprites in
  226. a single object.
  227.  
  228.   WARNING! If you are writing a screen scrolling game, you may
  229. encounter problems using sprites in conjunction with the SCREEN OFFSET
  230. and SCREEN DISPLAY commands. These generate a DMA clash between the
  231. sprite system and the screen bit-maps, and can occasionally lead to
  232. unwanted screen effects.
  233.  
  234.   This problem is only relevant if you are using hardware sprites 6/7.
  235. When the screen is shifted to the left with SCREEN OFFSET, the amount
  236. of time for your sprite updates is reduced, as the screen DMA has
  237. priority over the sprite system. Unfortunately, there isn't enough
  238. processing time to draw sprites 6/7, and they will therefore be
  239. corrupted on your display.
  240.  
  241.   To clear up this problem, create sprites 6/7 as individual hardware
  242. sprites and position them off the screen using negative coordinates.
  243. This will stop AMOS Basic from using them in your computed sprites.
  244. Providing sprites 6/7 are never displayed on the screen during your
  245. scrolling operations, all will be well.
  246.  
  247.  
  248. The sprite palette
  249. ==================
  250. The colours required by a hardware sprite are stored in the colour
  251. registers 16 to 31. Providing your current screen mode doesn't make use
  252. of these registers, the sprite colours will be completely separate from
  253. your screen colours. Interestingly enough, this is also the case for
  254. the 4096-colour Ham mode. So there's nothing stopping you from
  255. producing some mind-blowing Ham games with this system!
  256.  
  257.   However you will encounter real problems when using 32 or 64 colour
  258. screen in conjunction with three colour sprites. This is because the
  259. colours used by these sprites are grouped together in the following
  260. way:
  261.            Hardware sprites  Colour registers
  262.            ----------------  ----------------
  263.                  0 / 1         17 / 18 / 19
  264.                  2 / 3         21 / 22 / 23
  265.                  4 / 5         25 / 26 / 27
  266.                  6 / 7         29 / 30 / 31
  267.  
  268.    Colour registers 16,20,24 and 28 are treated as transparent.
  269.  
  270. The difficulty arises due to the way AMOS generates computed sprites.
  271. The hardware sprites used to produce these objects vary during the
  272. course of a game, so it's vital to ensure that the three colours used
  273. by each individual sprite are set to exactly the same values, otherwise
  274. the colours of your computed sprites will change unpredictably. Here's
  275. a small AMOS procedure which will perform the entire process for you       151
  276. automatically.
  277.  
  278.         Procedure INIT_SPRITES
  279.           Get Sprite Palette
  280.           For S=0 To 3
  281.             For C=0 To 2
  282.               Colour S*4+C+17,Colour(C)
  283.             Next C
  284.           Next S
  285.         Endproc
  286.  
  287. The above restriction does not, of course, apply to fifteen-colour
  288. sprites. If you want to make the most of the Extra Half Bright or
  289. 32-colour modes, you may find it easier to avoid using four-colour
  290. sprites altogether.
  291.  
  292.  
  293.  
  294.                     GET SPRITE PALETTE (grab sprite
  295.                          colours into screen)
  296.  
  297. GET SPRITE PALETTE [mask]
  298.  
  299. This loads the entire colour palette used for your sprite images into
  300. the current screen. The optional "mask" allows you to load just a
  301. selection of the colours from the sprite palette. Each of the 32
  302. colours is represented by a single bit in the mask, numbered from right
  303. to left. The rightmost bit represents the status of colour zero, the
  304. next vit colour 1, and so on. To load a colour simply set the
  305. appropriate bit to 1. If, for instance, you wanted to copy just the
  306. first four colours, you would set the bit pattern to:
  307.  
  308.         Get Sprite Palette %0000000000001111
  309.  
  310. Identically, since bobs use the same sprite bank as sprites, this
  311. command can also be used to load the colours of a bob.
  312.  
  313.  
  314. Controlling sprites
  315. ===================
  316.  
  317.  
  318.                  SET SPRITE BUFFER (set height of the
  319.                            hardware sprites)
  320.  
  321. SET SPRITE BUFFER n
  322.  
  323. This sets the work area in which AMOS creates the images of the
  324. hardware sprits. Acceptable values for n range from 16 to 256. TO set
  325. the correct value for n, simply examine the sprites in the sprite
  326. editor and work out which is the largest sprite length wise. ANy sprite
  327. that is larger than "n" will simply be truncated at the appropriate cut
  328. off point.
  329.  
  330.   SET SPRITE BUFFER is supplied for your use so that you can claim back
  331. any redundant memory our game or application simply doesn't use.
  332.  
  333.   The amount of memory consumed by the sprite buffer can be calculated
  334. using the formula:
  335.  
  336.         Memory = N*4*8*3 = N*96
  337.  
  338.   So the minimum buffer size is 1536 bytes and the maximum is 24k.
  339. Note: This command erases all current sprite assignments and resets the
  340. mouse cursor to its original state.
  341.  
  342.  
  343.  
  344.                     SPRITE OFF (remove one or more                         152
  345.                        sprites from the screen)
  346. SPRITE OFF [n]
  347.  
  348. The SPRITE OFF command removes one or more sprites from the screen. All
  349. current sprite movements are aborted. In order to restart them, you'll
  350. need to completely reinitialize your movement pattern.
  351.  
  352. SPRITE OFF    Removes all the sprites from display
  353.  
  354. SPRITE OFF n  Only deactivates sprite number n
  355.  
  356. Note that your sprites are automatically deactivated whenever you call
  357. up the AMOS Basic editor. They will be automatically returned to their
  358. original positions the next time you enter direct mode.
  359.  
  360.  
  361.  
  362.                SPRITE UPDATE (control sprite movements)
  363.  
  364. SPRITE UPDATE [ON/OFF]
  365.  
  366. The SPRITE UPDATE command provides you with total control of the
  367. movements of your sprites. Normally, whenever you move a sprite, its
  368. position is updated automatically during the next vertical blank period
  369. (see WAIT VBL). But if you are moving a lot of sprites using the SPRITE
  370. command, the updates will occur before all the sprites have been moved.
  371. This may result in a noticeable jump in yur movement patterns. In these
  372. circumstances, you can turn off the automatic updating system with the
  373. SPRITE UPDATE OFF command.
  374.  
  375.   Once your sprites have been succesfully moved, you can then slide
  376. them smoothly into place with a call to SPRITE UPDATE. This will
  377. reposition any sprites which have moved since your last update.
  378.  
  379.  
  380.  
  381.                =X SPRITE (get x coordinate of a sprite)
  382.  
  383. x=X SPRITE(n)
  384.  
  385. Returns the current x coordinate of sprite n, measured the hardware
  386. system. This command allows you to quickly check whether a sprite has
  387. passed of the edge of the Amiga's screen.
  388.  
  389.  
  390.  
  391.                =Y SPRITE (get y coordinate of a sprite)                    153
  392.  
  393. y=Y SPRITE(n)
  394.  
  395. Y SPRITE returns a sprite's vertical position. As usual, n refers to
  396. the number of the sprite and can range from 0 to 63. Remember, all
  397. sprite positions are measured in hardware coordinates. See EXAMPLE 11.3
  398.  
  399.  
  400.  
  401.                GET SPRITE (load a section of the screen
  402.                          into the sprite bank)
  403.  
  404. GET SPRITE [s,] i,x1,y1 TO x2,y2
  405.  
  406. This instruction enables you to grab images directly off the screen and
  407. turn them into sprites. The coordinates x1,y1 and x2,y2 define a
  408. rectangular area to be captured into the sprite bank. Normally all
  409. images are taken from the current screen. However it's also possible to
  410. grab the image from a specific screen using the optional screen number
  411. "s".
  412.  
  413.   Note: There are no limitations to the region that may be grabbed in
  414. this way. Providing your coordinates lie inside the existing screen
  415. borders, everything will be fine.
  416.  
  417.   i denotes the number of the new image. If there is no existing sprite
  418. with this number, a new image will be created automatically. AMOS wlil
  419. also take the trouble of reserving the sprite bank if it hasn't been
  420. previously defined. See EXAMPLE 11.4
  421.  
  422.   There's also an equivalent GET BOB instruction which is identical to
  423. GET SPRITE in every respect. Since the sprite bank is shared by both
  424. bobs and sprites, the images are in exactly the same format. So it's
  425. perfectly acceptable to use both instructions in conjunction with
  426. either bobs or sprites. Try changing the sprite instruction in the
  427. previous example to something like:
  428.  
  429.         Bob 1,0,0,1
  430.  
  431.  
  432. Conversion functions
  433. ====================
  434.  
  435.  
  436.                  =X SCREEN (convert hardware coordinates
  437.                  =Y SCREEN  into screen coordinates)
  438.  
  439. x=X SCREEN([n,] xcoord)
  440. y=Y SCREEN([n,] ycoord)
  441.  
  442. Transforms a hardware coordinate into a screen cordinate relative to
  443. the current screen. If the hardware coordinates lie outside the screen
  444. then both functions will return relative offsets from the screens
  445. boundaries. Type the following from direct mode:
  446.  
  447.         Print X Screen(130)
  448.  
  449. The result will be -2. This is because the x screen coordinate 0 is
  450. equal to hardware coordinate 128 and thus the conversion of 130 to a
  451. screen coordinate results in a position two pixels to the left of the
  452. screen.
  453.  
  454.   If the optional screen number is included then the coordinates will
  455. be returned relative to screen # n.
  456.  
  457.  
  458.  
  459.                   =X HARD (convert screen coordinates                      154
  460.                   =Y HARD  into hardware coordinates)
  461.  
  462. X=X HARD ([n,] xcoord)
  463.  
  464. These functions convert a screen coordinate into a hardware coordinate.
  465. There are four separate conversion functions, the above syntaz converts
  466. xcoord from a coordinate relative to the current screen to a hardware
  467. coordinate.
  468.  
  469. Y=Y HARD ([n,] ycoord)
  470.  
  471. Transforms a Y coordinate relative to the current screen into hardware
  472. coordinate. As before, n specififes a screen number for use with the
  473. functions. All coordinates will now be returned relative to this
  474. screen.
  475.  
  476.  
  477.  
  478.              =I SPRITE (return current image of a sprite)
  479.  
  480. Image=I SPRITE(n)
  481.  
  482. This function returns the current image number being used by sprite n.
  483. A value of zero will be reported if the sprite is not displayed.
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.                       12: BLITTER OBJECTS (BOBS)                           155
  493.                      ----------------------------
  494. While hardware sprites are certainly powerful, they do suffer from a
  495. couple of annoying restrictions. The solution is to make use of the
  496. Amiga's infamous Blitter chip. This is capable of copying images to
  497. the screen at rates approaching a million pixels per second! With the
  498. help of the blitter it's possible to create what are known as bobs.
  499.  
  500.   Bobs, like sprites, can be moved around completely independently of
  501. the screen without destorying any existing graphics. But unlike
  502. sprites, bobs are sroted as part of the current screen, so you can
  503. create them in any graphics mode you wish. This allows you to generate
  504. bobs with up to 64 colours. Furthermore the only limit to the number
  505. of bobs you can display is dictated by the available memory.
  506.  
  507.   Bobs are slightly slower than sprites and they consume considerably
  508. more memory. Therefore there's a trade-off between the speed of sprites,
  509. and the flexibility of bobs. Fortunately there's nothing stopping you
  510. from using both bobs and sprites in the same program.
  511.  
  512.  
  513.  
  514.                 BOB (draw a bob on the current screen)
  515.  
  516. BOB n,x,y,i
  517.  
  518. The BOB command creates bob n at coordinates x,y using the image # i.
  519.  
  520.   n is the identification number of the bob. Permissible values
  521. normally range from 0 to 63, but the number of bobs may be increased
  522. using an option from the AMOS configuration program. Providing you've
  523. enough memory, you can set this limit to any number you wish.
  524.  
  525.   x and y specify the position of the bob using standard screen
  526. coordinates. These coordinates are not the same as the hardware
  527. coordinates used by the equivalent SPRITE command. Like sprites, each
  528. bob is controlled through a *hot spot*. This may be changed at any time
  529. with the HOT SPOT command.
  530.  
  531.   i refers to an image which is to be assigned to the bob from the
  532. sprite bank. The format of this image is identical to that used by the
  533. sprites, so you can use the same images for either sprites or bobs.
  534.  
  535.   After you've created a bob, you can independently change either its
  536. position or its appearance by omitting one or more parameters from this
  537. instruction. Any of the numbers x,y or "image" may be left out, with
  538. the missing parameters retaining their original values. This is
  539. particularly useful if you are animating your bob with AMAL, as it
  540. allows you to move your object anywhere you like, without disturbing
  541. your existing animation sequence. However you must always include the
  542. commas in their original order. Example:
  543.  
  544.         Load "AMOS_DATA:Sprites/Octopus.abk"
  545.         Flash Off : Get Sprite Palette
  546.         Channel 1 To Bob 1
  547.         Bob 1,0,100,1
  548.         Amal 1,"Anim 0,(1,4)(2,4)(3,4)(4,4)"                               156
  549.         Amal On
  550.         For X=1 To 320
  551.           Bob 1,X,,
  552.           Wait Vbl
  553.         Next x
  554.  
  555. Whenever a bob is moved, the area underneath is replaced in its
  556. original position, producing an identical effect to the equivalent
  557. SPRITE command. Unlike STOS on the ST, each object is allocated its own
  558. individual storage area. This reduces the amount of memory used by
  559. bobs, and improves the overall performance dramatically. Due to the
  560. Blitter, of course, therse's no real comparison between STOS sprites
  561. and AMOS bobs.
  562.  
  563.   Although the BOB command works fine for small number of bobs, there's
  564. an annoying flicker when you try to use more than three or four objects
  565. on the screen at once. This happens because the bobs are updated at the
  566. same time as the screen. You can therefore see the bobs while they are
  567. being drawn which results in an unpleasant shimmering effect.
  568.  
  569.   One alternative for improving the quality of your animations is to
  570. just limit your bobs to the bottom quarter of the screen. Since bobs
  571. are redrawn extremely quickly, the updates can often be completed
  572. before the lower part of the screen has been displayed. This provides
  573. you with acceptably smooth movements while consuming very little
  574. memory, so it's a useful trick if you're running short of space. See
  575. EXAMPLE 12.1
  576.  
  577.   Obviously this cannot be seen as a serious solution to such a glaring
  578. problem. So before you throw away your copy of AMOS Basic in disgust,
  579. you'll be relieved to hear that there's a simple way of eliminating
  580. this flicker completely, even when you're using dozens of bobs anywhere
  581. on the screen:
  582.  
  583.  
  584.  
  585.              DOUBLE BUFFER (create a double screen buffer)
  586.  
  587. DOUBLE BUFFER
  588.  
  589. Creates a second invisible copy of the current screen. All graphics
  590. operations, including bob movements, are now performed directly in this
  591. *logical screen*, without disturbing your TV picture in the slightest.
  592. Once the image has been redrawn, the logical screen is displayed, and
  593. the original *physical* screen becomes the new logical screen. The
  594. entire process now cycles continuously, producing a rock solid display
  595. even when you're moving hundreds of bobs around the screen at once.
  596.  
  597.   The entire procedure is performed automatically by AMOS Basic, so
  598. after you've executed this instruction you can forget about it
  599. completely. Note that since the hardware sprites are always displayed
  600. using the current physical screen, this system will have absolutely no
  601. effect on any existing sprite animations.
  602.  
  603.   Double buffering works equally well in all of the AMIGA's graphics
  604. modes. It can even be used in conjuction with dual playfields. But be
  605. warned: Double buffering doubles the amount of memory used by your
  606. screens. If you attempt to double buffer too many screens, you'll
  607. quickly run out of memory. See EXAMPLE 12.2
  608.  
  609.   In practice, double buffering is an incredibly useful technique,
  610. which can be readily exploited for most types of games. It has seen
  611. service in the vast majority of commercial games, including Starglider
  612. - that's why it's such an integral part of AMOS Basic. A detailed
  613. explanation of this process can be found in the SCREENS chapter. ALso
  614. see the SCREEN SWAP and AUTOBACK commands.
  615.  
  616.  
  617.  
  618.                    SET BOB (set drawing mode of bob)                       157
  619.  
  620. SET BOB n,back,planes,minterms
  621.  
  622. The SET BOB command changes the drawing mode used to display a bob on
  623. the screen. n is the number of the bob you wish to affect.
  624.  
  625.   "back" chooses the way the background underneath your bob will be
  626. redrawn. There are three possibilities:
  627.  
  628.  - A value of 0 indicates that the area underneath your bob should be
  629.    saved in memory. The old image data is automatically replaced when
  630.    the bob is moved, resulting a smooth movement effect.
  631.  
  632.  - if the "back" parameter is positive then the original background
  633.    will be discarded altogether, and the area behind the bob will be
  634.    filled with colour "back"-1. This is ideal for moving bobs over a
  635.    solid block of colour such as a clear blue sky, as it's much faster
  636.    than the standard drawing system.
  637.  
  638.  - Turn of the redrawing process completely by loading "back" with a
  639.    negative value such as -1. You can now deactivate the automatic
  640.    updating process using BOB UPDATE, and manually move your bobs with
  641.    a call to BOB DRAW. This allows you to regenerate the screen
  642.    background using your own customised drawing routines.
  643.  
  644.   "planes" is a bit map which tells AMOS which screen planes your bob
  645. will be drawn in. As you may know, the Amiga's screen is divided up
  646. into a number of separate bit-planes. Each plane sets a single bit in
  647. the final colour which is displayed on the screen.
  648.  
  649.   The first plane is represnted by bit one, the second by bit two and
  650. so on. Normally the bob is drawn in all the bit-planes in the current
  651. screen mode. This corresponds to a bitpattern of %111111.
  652.  
  653.   By changing some of these bits to zero, you can omit selected colours
  654. from your bobs when they are drawn. This can be used to generate a
  655. number of intriguing screen effects.
  656.  
  657.   "minterms" selects the blitter mode used to draw your bobs on the
  658. screen. A full description of the available modes can be found in the
  659. section on SCREEN COPY. "minterm" is usually set to one of two values:
  660.  
  661.         %11100010   If the bob is used with a mask
  662.         %11001010   if NO MASK has been set
  663.  
  664. Feel free to experiment with the various combinations. There's no
  665. danger of crashing your Amiga if you make a mistake. Advanced Amiga
  666. users find the following information useful.
  667.  
  668.         Blitter source  Purpose                                            158
  669.         --------------  ------------------
  670.               A         Blitter mask
  671.               B         Blitter object
  672.               C         Destination screen
  673.  
  674. Note that you are recommended to use SET BOB *before* displaying your
  675. bobs on the screen. If you don't, the Amiga won't crahsh, and you won't
  676. get an error message, but your screen display may be corrputed.
  677.  
  678.  
  679.  
  680.                      NO MASK (remove blitter mask)
  681.  
  682. NO MASK [n]
  683.  
  684. As a default, a blitter mask is automatically created for every bob you
  685. display on the screen. This mask is combined with the screen background
  686. to make colour zero transparent. It's also used by the various
  687. collision detection commands.
  688.  
  689.   The NO MASK command removes this mask, and forces the entire image to
  690. be drawn on the screen. Any parts of the image in colour zero will now
  691. be displayed directly over the existing background.
  692.  
  693.   n is the image number whose mask is to be removed. This mask should
  694. never be erased if the image is active on the screen, otherwise the
  695. sasociated bob will be corrupted. If you must remove the mask in this
  696. way, it's important to deactivate the relevant bobs with BOB OFF first.
  697. Here's an example:
  698.  
  699.         Centre "Click mouse button to remove mask"
  700.         Double buffer : Load "AMOS_DATA:Sprites/Octopus.abk"
  701.         Get Sprite Palette
  702.         Do
  703.           Bob 1,X Screen(X Mouse),Y Screen(Y Mouse),1
  704.           If Mouse Click Then Bob Off : No Mask 1
  705.         Loop
  706.  
  707. See MAKE MASK
  708.  
  709.  
  710.                         AUTOBACK (set automatic
  711.                          screen copying mode)
  712.  
  713. AUTOBACK n
  714.  
  715. When you are using a double bufferend screen, it's essential to
  716. synchronize your drawing operations with the movements of your blitter
  717. objects. Remember that each double buffered screen consists of two
  718. separate displays. There's one screen for the current picture, and
  719. another for the image whilst it's being constructed. If the background
  720. underneath a bob changes while it's being redrawn, the contents of
  721. these screens will be different, and you'll get an intense and annoying
  722. flickering efect.
  723.  
  724.   The unique AMOS AUTOBACK system provides you with a perfect solution
  725. to this problem. It allows you to generate your graphics in any one of
  726. three graphics modes, depending on the precise requirements of your
  727. program. Just for a change, we'll list tese options in reverse order.
  728.  
  729.  
  730. AUTOBACK 2 (automatic mode - default)                                      159
  731.  
  732.   In this mode, all drawing operations are automatically combined with
  733.   the bob updates. So anything you draw on the screen will be displayed
  734.   directly underneath your bobs, as if by magic. The principles behing
  735.   this system can be demonstrated by the following code:
  736.  
  737.         Bob Clear : Rem    Draw on first screen ... Remove Bobs
  738.         Plot 150,100 : Rem This can be anything you wish
  739.         Bob Draw : Rem     Redraw bobs
  740.         Screen Swap : Rem  Next Screen
  741.         Wait Vbl
  742.         Bob Clear
  743.         Plot 150,100 : Rem Perform your operation a second time
  744.         Bob Draw
  745.         Screen Swap : Rem  Get back to first screen
  746.         Wait Vbl
  747.  
  748.   As you can see, all screen updates are performed exactly twice.
  749.   There's one operation for both the logical and the physical screen.
  750.   See EXAMPLE 12.3 for a demonstration.
  751.  
  752.     One obvious side effect, is that your graphics now take twice as
  753.   long to be drawn. Furthermore, the program will be halted by at least
  754.   2 vertical blanks, every time you output something to the screen.
  755.   This may cause annoying delays in the execution of critical
  756.   activities such as collision detection.
  757.  
  758.  
  759. AUTOBACK 1 (half-automatic mode)
  760.  
  761.   Performs each graphical operation in both the physical and logical
  762.   screens. Absolutely no account is taken of your bobs, so you should
  763.   only use this system for drawing outside the current playing area.
  764.  
  765.     Unlike the standard mode, there's no need to halt your program
  766.   until the next vertical blank. Mode 1 is therefore ideal for objects
  767.   such as control panels or hi-score tables, which need to be updated
  768.   continually during the game.
  769.  
  770.  
  771. AUTOBACK 0 (manual mode)
  772.  
  773.   Stops the AUTOBACK system in it's tracks. All graphics are now output
  774.   straight to the logical screen at the maximum possible speed. You
  775.   should use this option if you need to repeatedly redraw large
  776.   sections of your background screen during the course of a game.
  777.   This will allow you to safely perform your collision detection
  778.   routines at regural intervals, without destroying the overall quality
  779.   of the animation effects. Here's a typical program loop for you to
  780.   examine.
  781.  
  782.         Bob Update Off
  783.         Repeat
  784.         Screen Swap
  785.         Wait Vbl
  786.         Bob Clear
  787.         Rem Now redraw any of your gfxs which have changed                 160
  788.         Rem Perform your game routines (Collision detection etc...)
  789.         Bob draw
  790.         Until WIN
  791.  
  792. Note that this procedure will ONLY work if there's a smooth progression
  793. from screen to screen. It's entirely up to you to keep the contents of
  794. physical and logical screen in step with each other. An example of this
  795. technique can be found in EXAMPLE 12.4
  796.  
  797.   Supposing for instance, you wanted to display a bob over a series of
  798. random blocks. You might try to use a routine like:
  799.  
  800.         Load "AMOS_DATA:Sprites/Sprites.abk" : Flash Off
  801.         Get Sprite Palette : Double Buffer : Cls 0 : Autoback 0
  802.         Update Off : Bob 1,160,100,1
  803.         Do
  804.           Bob Clear
  805.           X=Rnd(320)+1 : Y=Rnd(200)+1 : W=Rnd(80)+1
  806.           H=Rnd(50)+1 : I=Rnd(15)
  807.           Ink I : Bar X,Y To X+W,Y+H
  808.           Rem <this would normally call your collision detection routine>
  809.           Bob Draw
  810.           Screen swap : Wait Vbl
  811.         Loop
  812.  
  813. But since there's no relationship between the physical and logical
  814. screens, the display will now flick continuously from screen to screen.
  815. To overcome this problem, you'll need to mimic the original AUTOBACK
  816. system. Replace the lines in the previous example between the lines
  817. Do and Loop  as follows:
  818.  
  819.           Rem Update first screen
  820.           Screen Swap : Wait Vbl
  821.           Bob Clear
  822.           X=Rnd(320)+1 : Y=Rnd(200)+1 : W=Rnd(80)+1
  823.           H=Rnd(50)+1 : I=Rnd(15)
  824.           Ink I : Bar X,Y To X+W,Y+H
  825.           Bob Draw
  826.           Rem Update second screen
  827.           Screen Swap : Wait Vbl
  828.           Bob Clear
  829.           Ink I : Bar X,Y To X+W,Y+H
  830.           Bob Draw
  831.  
  832. The two screens are now updated with exactly the same information, and     161
  833. the display remains as steady as a rock, even though there's a great
  834. deal of activity going on in the background.
  835.  
  836.   Autoback can be safely used at any point in your program. So it's
  837. perfectly possible to use separate drawing methods for the different
  838. parts of your screen. It's also totally compatible with all graphics
  839. operations including Blocks, Icons, and Windowing.
  840.  
  841.  
  842. Bob Control commands
  843. ====================
  844.  
  845.  
  846.                    BOB UPDATE (control bob movements
  847.  
  848. BOB UPDATE [ON/OFF]
  849.  
  850. Normally all bobs are updated once every 50th of a second using a
  851. built-int interrupt routine. Alhouth this is convenient for most
  852. programs, there are some applications which require much finer control
  853. over the redrawing process.
  854.  
  855.   BOB UPDATE OFF turns off the bob updates and deactivates all
  856. automatic screen switching operations if they've been selected. You may
  857. now redraw your bobs at the most appropriate point in your program
  858. using the BOB UPDATE command. This is ideal when you are animating a
  859. large number of objects as it enables you to move your bobs into
  860. position before drawing them on the screen. Inevitably this results in
  861. far smoother movements in your game.
  862.  
  863.   One word of warning: The bob updates will only occur at the NEXT
  864. vertical blank. Also note that BOB UPDATE will always redraw the bobs
  865. on the current logical screen, so if you forget to use the SCREEN SWAP
  866. command, nothing will apparently happen.
  867.  
  868.  
  869.  
  870.             BOB CLEAR (remove all the bobs from the screen)
  871.  
  872. BOB CLEAR
  873.  
  874. Removes all active bobs from the screen, and redraws the background
  875. regions underneath. It's inteded for use with BOB DRAW to provide an
  876. alternative to the standard BOB UPDATE command
  877.  
  878.  
  879.  
  880.                         BOB DRAW (redraw bobs)
  881.  
  882. BOB DRAW
  883.  
  884. Whenever the bobs are redrawn on the screen, the following steps are
  885. automatically performed:
  886.  
  887.  1. All active bobs are removed from the LOGICAL screen and the
  888.     background regions are replaced. This step is performed by BOB
  889.     CLEAR.
  890.  2. A list is made of all bobs which have moved since the previous
  891.     update.
  892.  3. The background regions under the new screen coordinates are saved
  893.     in memory.
  894.  4. All active bobs are redrawn at their new positions on the logical      162
  895.     screen
  896.  5. If the DOUBLE BUFFER feature has been activated, the physical
  897.     and logical screens are now swapped
  898.  
  899. The BOB DRAW command performs steps 2 to 4 of this process directly.
  900. Supposing you wished to create a screen scrolling arcade game. In this
  901. situation, it would be absolutely vital for your scrolling operations
  902. to be perfectly synchronized with movement effects. If the aliens were
  903. to move while the scrolling was taking place, their background areas
  904. would be redrawn at the wrong place. This would totally corrupt your
  905. display, and would result in a hopeless jumble on the screen. Load
  906. EXAMPLE 12.5 for a demonstration of this process.
  907.  
  908.  
  909.  
  910.                    =X BOB (get X coordinate of bob)
  911.  
  912. x1=X BOB(n)
  913.  
  914. Returns the current X coordinate of bob number n. This coordinate is
  915. measured relative to the current screen. See also Y SPRITE, X MOUSE and
  916. Y MOUSE.
  917.  
  918.  
  919.  
  920.                    =Y BOB (get Y coordinate of bob)
  921.  
  922. y1=Y BOB(n)
  923.  
  924. Y BOB complements the X BOB command by returning the Y coordinate of
  925. bob number n. This value will be returned using normal screen
  926. coordinates.
  927.  
  928.  
  929.  
  930.                  =I BOB (return current image of bob)
  931.  
  932. Image=U BOB(n)
  933.  
  934. This function returns the current image number being used by bob n. A
  935. value of zero will be reported if the bob isn't displayed.
  936.  
  937.  
  938.  
  939.                 LIMIT BOB (limit a bob to a rectangular
  940.                          region of the screen)
  941.  
  942. LIMIT BOB [n,] x1,y1 TO x2,y2
  943.  
  944. This command restricts the visibility of your bobs to a rectangular
  945. screen area enclosed by the coordinates x1,y1 to x2,y2. The x
  946. coordinates are rounded up to the nearest 16-pixel boundary. Note that
  947. the width of this region must always be greater than the width of your
  948. bobs, otherwise you'll get an "illegal function call" error.
  949.  
  950.   If it's included, n specifies the number of a single bob which is to
  951. be affected by this instruction, otherwise *all* bobs will be
  952. restricted. You can restore the visibility limit to the entire entire
  953. screen by typing:
  954.  
  955.         LIMIT BOB
  956.  
  957.  
  958.  
  959.                  GET BOB (load a section of the screen                     163
  960.                          into the sprite bank)
  961.  
  962. GET BOB [s,] i,x1,y1 TO x2,y2
  963.  
  964. This instruction is identical to the GET SPRITE command. It grabs an
  965. image into the sprite bank from the current screen.
  966.  
  967.   x1,y1 to x2,y2 are the coordinates of the top and bottom corners of
  968. the rectangular area to be grabbed.
  969.  
  970.   i specifies the image number which is to be loaded with this area. s
  971. selects an optional screen number from which the image is to be taken.
  972. See GET SPRITE for more details. See also EXAMPLE 12.6.
  973.  
  974.  
  975.  
  976.              PUT BOB (fix a xopy of a bob onto the screen)
  977.  
  978. PUT BOB n
  979.  
  980. This is the exact opposite of the previous GET BOB command. The action
  981. of PUT BOB is to place a copy of bob number n at its present position
  982. on the screen. It works by preventing the background underneath the bob
  983. from being redrawn during the next vertical blank period. In order to
  984. synchronise the bob updates with the screen display, you should always
  985. follow this command with a WAIT VBL instruction.
  986.  
  987.   Note that after this instruction has been performed, the original bob
  988. may be moved or animated with no ill efects.
  989.  
  990.  
  991.  
  992.                PASTE BOB (draw an image from the sprite
  993.                           bank on the screen)
  994.  
  995. PASTE BOB x,y,i
  996.  
  997. The PASTE BOB command draws a copy of image number i at *screen*
  998. coordinates x,y. Unlike PUT BOB this image is drawn on the screen
  999. immediately, and all the normal clipping rules are obeyed. See PASTE
  1000. ICON.
  1001.  
  1002.  
  1003.                 BOB OFF (remove a bob from the display)
  1004.  
  1005. BOB OFF [n]
  1006.  
  1007. Occasinoally, you may wish to remove certain bobs from the screen
  1008. altogether. The BOB OFF command erases bob number n from the screen and
  1009. terminates any associated animations. If n is omitted, all bobs will be    164
  1010. removed by this instruction.
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.                           13: OBJECT CONTROL                               165
  1017.                       ---------------------------
  1018. In this section you will find out how the various objects generated
  1019. using the sprite and bob commands can be controlled from within an AMOS
  1020. Basic program. The topics under discussion include collision detection,
  1021. using the mouse cursor and reading the joystick.
  1022.  
  1023.  
  1024. The mouse pointer
  1025. =================
  1026. The mouse cursor provides the games programmer with a valuable
  1027. alternative to the standard joystick. With the CHANGE MOUSE command you
  1028. can replace the mouse with an image in the current sprite bank. There's
  1029. also a group of instructions which allow you to determine both the
  1030. position and status of this mouse at any time. These include the
  1031. X MOUSE, Y MOUSE and MOUSE KEY instructions.
  1032.  
  1033.  
  1034.  
  1035.               HIDE (remove mouse pointer from the screen)
  1036.  
  1037. HIDE [ON]
  1038.  
  1039. This command removes the mouse pointer from the screen completely. A
  1040. count of the number of occasions you have called this function is kept
  1041. internally by the system. This needs to be matched by an equal number
  1042. of SHOW instructions before the pointer will be returned on the screen.
  1043.  
  1044.   There's also another version of this instruction which can be
  1045. accessed with HIDE ON. This ignores the count and *always* hides the
  1046. mouse, no matter how many times you've called the SHOW command.
  1047.  
  1048.   Note that HIDE only makes the mouse pointer invisible. It has no
  1049. effect on any other AMOS commands, so you can still use X MOUSE and
  1050. Y MOUSE functions to read the coordinates of the mouse as normal.
  1051.  
  1052.  
  1053.  
  1054.                    SHOW (activate the mouse pointer)
  1055.  
  1056. SHOW [ON]
  1057.  
  1058. This returns the mouse pointer to the screen after a HIDE instruction.
  1059. Works the same way that HIDE does.
  1060.  
  1061.  
  1062.  
  1063.                    CHANGE MOUSE (change the shape of
  1064.                           the mouse pointer)
  1065.  
  1066. CHANGE MOUSE m
  1067.  
  1068. This allows you to change the shape of the mouse at any time. Three
  1069. mouse patterns are provided as standard. These can be assigned using
  1070. the numbers 1-3.
  1071.  
  1072. If you specify a value m greater than 3, this is assumed to refer to an    166
  1073. image stored in the sprite bank. The number of this image is determined
  1074. using the expression I=m-3. So image number 1 would be installed by a
  1075. value of 4.
  1076.  
  1077.   In order to use this option, your sprite image must be exactly 16
  1078. pixels wide and have no more than four colours. However there's no such
  1079. limit to the height of your image.
  1080.  
  1081.  
  1082.  
  1083.                =MOUSE KEY (read status of mouse buttons)
  1084.  
  1085. k=MOUSE KEY
  1086.  
  1087. Enables you to quickly check whether one or more of the mouse keys have
  1088. been pressed. It returns a bit-pattern which holds the current status
  1089. of the mouse buttons.
  1090.  
  1091.         Bit 0   Set to 1 if the LEFT   button pressed, otherwise zero.
  1092.         Bit 1   Set to 1 if the RIGHT  button pressed, otherwise zero.
  1093.         Bit 2   Set to 1 if the MIDDLE button pressed (if available).
  1094.  
  1095.  
  1096.  
  1097.                 =MOUSE CLICK (check for a mouse click)
  1098.  
  1099. c=MOUSE CLICK
  1100.  
  1101. Checks wheter the user has "clicked" on a mouse button. Uses the same
  1102. bit pattern indication as =MOUSE KEY.
  1103.  
  1104. One shot tests are only set to 1 when the mouse key has just been
  1105. pressed. These bits are automatically reset to zero after they've been
  1106. tested once. So they will only check for a single key press at a time.
  1107.  
  1108.  
  1109.  
  1110.        =XMOUSE= (get/set the X coordinate of the mouse pointer)            167
  1111.  
  1112. x1=X MOUSE
  1113.  
  1114. X MOUSE returns the current X coordinate of the mouse pointer in
  1115. hardware notation. You can also use this function to move the mouse on
  1116. to a specific screen position. This can be achieved by assigning X
  1117. MOUSE with a value, just like a Basic variable, for example:
  1118.  
  1119.         X MOUSE=150
  1120.  
  1121.  
  1122.  
  1123.        =YMOUSE= (get/set the Y coordinate of the mouse pointer)
  1124.  
  1125. y1=Y MOUSE
  1126.  
  1127. Returns the Y coordinate of the mouse pointer. This can also be used to
  1128. set the Y position of the mouse pointer the same way as using X MOUSE.
  1129. See EXAMPLE 13.1 for an example of the X MOUSE and Y MOUSE.
  1130.  
  1131.  
  1132.  
  1133.                  LIMIT MOUSE (limit mouse to a section
  1134.                             of the screen)
  1135.  
  1136. LIMIT MOUSE x1,y1 TO x2,y2
  1137.  
  1138. Restricts mouse movements to the rectangular area defined by the
  1139. hardware coordinates (x1,y1) and (x2,y2). Note that unlike LIMIT BOB,
  1140. the mouse is completely trapped inside this zone and cannot be moved
  1141. beyond it. Simply use this instruction with no parameters to restore
  1142. the mouse to the full screen area.
  1143.  
  1144.         LIMIT MOUSE
  1145.  
  1146. See also EXAMPLE 13.2 from the manual folder for a demonstration.
  1147.  
  1148.  
  1149. Reading the joystick
  1150. ====================
  1151. AMOS Basic includes six functions which allow you to immediately check
  1152. the movements of a joystick insterted in either of the available
  1153. sockets.
  1154.  
  1155.  
  1156.  
  1157.                          =JOY (read joystick)                              168
  1158.  
  1159. d=JOY(j)
  1160.  
  1161. This function returns a binary number which represnts the current
  1162. status of a joystick in port number j. Normally your joystick will be
  1163. placed in the left socket (number 1). However you can remove the mouse
  1164. from the right-hand socket and replace it with a joystick. This can be
  1165. accessed using port # 0.
  1166.  
  1167.   The state of the joystick can be read by inspecting the pattern of
  1168. binary bits in the result. Each bit indicates whether a specific action
  1169. has been performed by the user. If a bit is set to one then the test
  1170. has proved positive and the joystick has been moved in the appropriate
  1171. direction. Here's a list of the various bits and their meanings:
  1172.  
  1173.         Bit Number   Significance
  1174.         ----------   ------------
  1175.             0        Joy moved up
  1176.             1            "     down
  1177.             2            "     left
  1178.             3            "     right
  1179.             4        Fire button pressed
  1180.  
  1181. See EXAMPLE 13.3
  1182.  
  1183. You can also use the following commands, if you are not familiar with
  1184. this binary notation:
  1185.  
  1186.  
  1187.  
  1188.                 =JLEFT(j) (test joystick movement left)
  1189.                =JRIGHT(j) (test joystick movement right)
  1190.                   =JUP(j) (test joystick movement up)
  1191.                 =JDOWN(j) (test joystick movement down)                    169
  1192.  
  1193. x=JLEFT(j)
  1194. x=JRIGHT(j)    These functions return a value of -1(true) if the
  1195. x=JUP(j)       joystick in port j has been pulled to the associated
  1196. x=JDOWN(j)     direction. Value 0 is reported, if the condition is
  1197.                false (joystick hasn't been moved to the asked
  1198.                direction).
  1199.  
  1200.  
  1201. Detecting collisions
  1202. ====================
  1203. If you're writing an arcade game it's vital to be able to accurately
  1204. check for collisions between the various objects on the screen. AMOS
  1205. Basic includes five powerful functions which allow you to perform these
  1206. tests quickly and easily.
  1207.  
  1208.  
  1209. Detecting collisions with a sprite
  1210. ----------------------------------
  1211.  
  1212.  
  1213.                  SPRITE COL (detect collisions between
  1214.                          two hardware sprites)
  1215.  
  1216. c=SPRITE COL (n [,s TO e])
  1217.  
  1218. This provides you with a simple way of testing to see whether two or
  1219. more sprites have collided on the screen. The number n refers to an
  1220. active hardware sprite which is to be clicked for a collision. If a
  1221. collision has occurred a value of -1(true) will be returned, otherwise
  1222. the result will be set to 0 (false).
  1223.  
  1224.   The standard from of this function checks for all collisions. But you
  1225. can also test a whole group of sprites using an extended version of the
  1226. command:
  1227.  
  1228.         c=SPRITE COL n,s TO e
  1229.  
  1230. The above instruction checks for collisions between sprite n and
  1231. sprites s to e (inclusive). Once you've detected a collision, you can
  1232. then get the individual sprite numbers which have vollided using the
  1233. COL function.
  1234.  
  1235.   NOTE that in order to use this function, you'll need to create a
  1236. sprite mask with the MASK command first, otherwise your collisions will
  1237. not be detected. A detailed example of this command can be found in
  1238. EXAMPLE 13.4.
  1239.  
  1240.  
  1241. Detecting collisions with a bob                                            170
  1242. -------------------------------
  1243.  
  1244.  
  1245.                   BOB COL (detect collisions between
  1246.                          two blitter objects)
  1247.  
  1248. c=BOB(n, [,s TO e])
  1249.  
  1250. The BOB COL function checks bob number n for a collision with another
  1251. bob. If a collision has been detected, the value returned in c will be
  1252. set to -1 (true), otherwise it will be 0.
  1253.  
  1254.   Normally the command will check for all collisions, but you can
  1255. specify a collection of bobs to be tested using the optional range
  1256. parameters s to e. The status of these bobs can be individually
  1257. examined with the COL command. See EXAMPLE 13.5.
  1258.  
  1259.  
  1260. Collisions between bobs and sprites
  1261. -----------------------------------
  1262.  
  1263.  
  1264.               SPRITEBOB COL (test for a collision between
  1265.                            sprites and bobs)
  1266.  
  1267. c=SPRITEBOB COL(n [,s TO e])
  1268.  
  1269. This function checks for a collision between SPRITE n ane one or more
  1270. BOBS. The value of c will be either -1 if a collision has been
  1271. discovered, or 0 if there have been no collisions. The starting and
  1272. ending points specify that collisions will only be detected between the
  1273. bobs s to e. If they are not included then all active bobs will be
  1274. tested by this instruction.
  1275.  
  1276.   WARNING! Collision detection between a sprite and a bob is only
  1277. possible on a low resolution screen. In HiRes mode, the pixel sizes
  1278. used for bobs and sprites are totally different, and the results from
  1279. this function will be unreliable.
  1280.  
  1281.  
  1282.  
  1283.               BOBSPRITE COL (test for a collision between
  1284.                            bobs and sprites)
  1285.  
  1286. c=BOBSPRITE COL(n, [,s TO e])
  1287.  
  1288. The BOB SPRITE COL function checks for collisions between a single bob
  1289. and several sprites. The results and usage of this instruction are
  1290. same as in the SPRITEBOB COL. See EXAMPLE 13.6.
  1291.  
  1292.  
  1293.  
  1294.                  =COL (test the status of a sprite or
  1295.               bob after a collision detection intruction)
  1296.  
  1297. c=COL(n)
  1298.  
  1299. The COL array holds the status of all the objects which have been
  1300. previously tested by the collision detection functions.
  1301.  
  1302.   Each object you have checked is associated with one element in this
  1303. array. This element will be loaded with -1 if a collision has been
  1304. detected with object number n, or 0 if it has not. The numbering system
  1305. is simple: The first element in the array holds the status of object
  1306. number 1, the second represents object number 2, and so on. See EXAMPLE
  1307. 13.7.
  1308.  
  1309.   If you are using the SPRITE COL or BOBSPRITE COL instructions then
  1310. the objects will be hardware sprites, otherwise they will be bobs. In
  1311. order to avoid confusion, it's sensible to call this instructoin
  1312. immediatly after the relevant detection command.
  1313.  
  1314.  
  1315.  
  1316.                 HOT SPOT (set the hot spot for an image                    171
  1317.                           in the sprite bank)
  1318.  
  1319. HOT SPOT image,x,y
  1320. HOT SPOT image,p
  1321.  
  1322. This command sets the hot spot of an image stored in the current sprite
  1323. bank. The hot spot of the object is used as a reference point for all
  1324. coordinate calculations. There are two versions of this instruction.
  1325.  
  1326.         HOT SPOT image,x,y
  1327.  
  1328. x and y coordinates measured from the top left corner of the image.
  1329. These coordinates will be added to the sprite bank or bob coordinate to
  1330. position an object precisely on the screen.
  1331.  
  1332.               Sprite image
  1333.               +----------+        Note that it's perfectly
  1334.               :          :        lefal for the hot spot
  1335.               : x        :        to lie outside the
  1336.               :<-->*     :        actual image.
  1337.               :  hot spot:
  1338.               +----------+
  1339.  
  1340.         HOT SPOT image,p
  1341.  
  1342. This is a short form of the instruction which moves the hot spot to one
  1343. of nine predefined positions. The positions are shown in the diagram
  1344. below where the centre point of the image is represent by a value of       172
  1345. $11.
  1346.  
  1347.         $00     $10     $20
  1348.         $01     $11     $21        See EXAMPLE 13.8.
  1349.         $02     $12     $22
  1350.  
  1351.  
  1352.  
  1353.                         MAKE MASK (make a mask
  1354.                around an image for collision detection)
  1355.  
  1356. MAKE MASK [n]
  1357.  
  1358. Defines a mask around image number n in the sprite bank. This is used
  1359. by all the AMOS Basic collision detection commands. You should
  1360. therefore create a mask for every object you wish to check. If you omit
  1361. the image number n, then a mask will be generated for each image in the
  1362. sprite bank. This may take a little time.
  1363.  
  1364.   It's important to note that masks are generated automatically when a
  1365. bob is first drawn on the screen. This might cause a significant delay
  1366. in the running of your program, so it's worthwhile placing an explicit
  1367. call to MAKE MASK during your initialisation procedure.
  1368.  
  1369.  
  1370. Collisions with rectangular blocks
  1371. ----------------------------------
  1372. AMOS Basic includes a number of functions which allow you to quickly
  1373. check whether a sprite or bob has entered a rectangular region of the
  1374. screen.
  1375.  
  1376.   These screen zones are especially useful for collision detection in
  1377. rebound games such as Arkanoid as each block can be assignet its own
  1378. individual screen zone. You can also use zones to construct the buttons
  1379. and switches needed for control panels and dialogue boxes.
  1380.  
  1381.  
  1382.  
  1383.            RESERVE ZONE (reserve space for a detection zone)
  1384.  
  1385. RESERVE ZONE [n]
  1386.  
  1387. RESERVE ZONE allocates enough memory for exactly n detection zones.
  1388. This command should always be used before defining a zone with SET
  1389. ZONE.
  1390.  
  1391.   The only limit to the number of zones is the amount of available
  1392. memory, so it's perfectly feasible to define hundreds or even thousands
  1393. of zones in one of your programs. To erase the current zone definitions
  1394. and restore the memory back to the main program, simply type
  1395.  
  1396.         RESERVE ZONE    with no parameters.
  1397.  
  1398.  
  1399.  
  1400.                    SET ZONE (set a zone for testing)
  1401.  
  1402. SET ZONE z,x1,y1 TO x2,y2
  1403.  
  1404. Defines a rectangular zone which can be subsequently tested using the
  1405. various ZONE commands. z specifies the number of the zone to be created
  1406. and x1,y1 and x2,y2 input the coordinates of the top left and bottom
  1407. right hand corners of the rectangle.
  1408.  
  1409.   Before using this instruction you'll need to reserve some space for
  1410. your zones with RESERVE ZONE.
  1411.  
  1412.  
  1413.  
  1414.                    =ZONE (return the zone under the                        173
  1415.                    the requested screen coordinates)
  1416.  
  1417. t=ZONE([s],x,y)
  1418.  
  1419. ZONE returns the number of the screen zone at the graphic coordinates
  1420. x,y. Normally the coordinates are relative to the current screen - you
  1421. can also include an optional screen number s in this function.
  1422.  
  1423.   After ZONE has been called, t will hold either the number of the zone
  1424. at the specified coordinates or a value of 0 (false).
  1425.  
  1426.   Note that ZONE only returns the first zone at these coordinates - it
  1427. won't detect any other zones which lie inside this region.
  1428.  
  1429.   It is possible to use this function in conjunction with X BOB and
  1430. Y BOB functions to detect whether a bob has entered a specific screen
  1431. zone. This can be accomplished using the following code:
  1432.  
  1433.         X=Zone(X bob(n),Y Bob(n))
  1434.  
  1435. See Examples 13.9 and 13.10.
  1436.  
  1437.  
  1438.  
  1439.                    =HZONE (return the zone under the
  1440.                     requested hardware coordinates)
  1441.  
  1442. t=HZONE([s],x,y)
  1443.  
  1444. HZONE is almost identical to ZONE except that the screen position is
  1445. now measured in hardware coordinates. You can therefore use this
  1446. function to detect when a hardware sprite enters one of your screen
  1447. zones. For example:
  1448.  
  1449.         X=Hzone(X Sprite(n),Y Sprite(n))
  1450.  
  1451. See also EXAMPLE 13.11, and ZONE, MOUSE ZONE, SET ZONE and ZONE$
  1452.  
  1453.  
  1454.  
  1455.               =MOUSE ZONE (check wheter the mouse pointer
  1456.                           has entered a zone)
  1457.  
  1458. x=MOUSE ZONE
  1459.  
  1460. The MOUSE ZONE function returns the number of the screen zone currently
  1461. occupied by the mouse pointer. It's equibalent to the line:
  1462.  
  1463.         X=Hzone(X mouse,Y mouse)
  1464.  
  1465.  
  1466.  
  1467.                        RESET ZONE (erase a zone)                           174
  1468.  
  1469. RESET ZONE [z]
  1470.  
  1471. This command permanently deactivats any of the zones created by SET
  1472. ZONE. If the optional zone number z is included then only this zone
  1473. will be reset, otherwise all the zones will be affected. Note that
  1474. RESET ZONE only erases the zone definitions, it does not return the
  1475. memory allocated by RESERVE ZONE.
  1476.  
  1477.  
  1478. Bob priority
  1479. ============
  1480.  
  1481.  
  1482.             PRIORITY ON/OFF (change between priority modes)
  1483.  
  1484. PRIORITY ON/OFF
  1485.  
  1486. Each bob is assigned a priority value ranging from 0-63. Amos basic
  1487. uses this number to decide which order the objects should be displayed
  1488. on the screen. As a rule, any bob with the highest priority will always
  1489. be displayed in front if any objects with a lower priority. The
  1490. priority value is taken directly from the number of a Bob.
  1491.  
  1492.   You should remember this fact when assigning numbers to your bobs.
  1493. The choise of number can have wide ranging effects on the appearance of
  1494. your objects on the screen.
  1495.  
  1496.   In addition to the standard system, it's also possible to arrange the
  1497. bobs according to their position on the screen. PRIORITY ON assigns the
  1498. greatest priority values to the bobs with the highest Y coordinates.
  1499. This allows you to create a useful illusion of perspective in your
  1500. games. Look at the example below:
  1501.  
  1502.         Load "AMOS_DATA/Sprites/Monkey_right.abk" : Cls : Flash Off
  1503.         Get Sprite Palette
  1504.         Priority Off : Rem Set normal mode
  1505.         Bob 1,160,100,2 : Bob 2,0,72,2 : Bob 3,320,128,2
  1506.         Channel 2 To Bob 2 : Channel 3 to Bob 3
  1507.         Amal 2," Loop: M 320,0,320 ; M -320,0,320 ; Jump Loop"
  1508.         Amal 3," Loop: M -320,0,320 ; M 320,0,320 ; Jump Loop"
  1509.         Amal On
  1510.         Wait Key
  1511.         Priority On : Rem Set Y mode
  1512.         Wait Key
  1513.  
  1514. Normally, both moving bobs pass below the object in the centre. When
  1515. you change the priority system with a call to PRIORITY ON, the bobs are
  1516. now ranked in order of their increasing Y coordinates. So bob three
  1517. moves aboce bob one while at the same time, bob two passes smoothly
  1518. behind it.
  1519.  
  1520.   HINT: It's usually best to position the Hot Spot of the sprite at its
  1521. base. This is because the Y coordinates used by this command relate to
  1522. the position of the Hot Spot on the screen. Also notice that the
  1523. PRIORITY OFF instruction can be utilised to reset the priority back to
  1524. normal.
  1525.  
  1526.  
  1527. Miscellaneous commands                                                     175
  1528. ======================
  1529.  
  1530.  
  1531.              UPDATE (change automatic sprite/bob updates)
  1532.  
  1533. UPDATE [ON/OFF]
  1534.  
  1535. Normally any objects you draw on the screen will be automatically
  1536. redisplayed whenever they are animated or moved. This feature can be
  1537. temporarily halted using the UPDATE OFF command. When the updates are
  1538. not active the SPRITE, BOB and AMAL commands apparently have no effect.
  1539. Actually, all your animations are working correctly - it's just that
  1540. the results are not being displayed on the screen. You can force this
  1541. redrawing operation at any time using the UPDATE command. Here are the
  1542. three different forms of the UPDATE instruction.
  1543.  
  1544.         UPDATE OFF
  1545.  
  1546. Turns of the automatic updating.
  1547.  
  1548.         UPDATE
  1549.  
  1550. Redraws any sprites which have changed their original positions
  1551.  
  1552.         UPDATE ON
  1553.  
  1554. Returns the sprite updating to normal. See EXAMPLE 13.12.
  1555.  
  1556. 14: AMAL                                    1
  1557. If you wish to generate the smooth movement required in an arcade game,
  1558. it's necessary to move each object on the screen dozens of times a
  1559. second. This is a real struggle even in machine code and it's way
  1560. beyond the abilities of the fastest version of Basic.
  1561.  
  1562.   AMOS sidesteps this problem by incorporating a powerful animation
  1563. language which is executed independently of your Basic programs. This
  1564. is capable of generating high speed animation effects which would be
  1565. impossible in standard Basic.
  1566.  
  1567.   The (AM)os (A)nimation (L)anguage (AMAL) is unique to AMOS Basic. In
  1568. can be used to animate anything from a sprite to an entire scren at
  1569. incredible speed. Up to 16 AMAL programs can be executed simultaneously
  1570. using interrupts.
  1571.  
  1572.   Each program controls the movements of a single object on the screen.
  1573. Objects may be moved in complex predefined attack patterns, created
  1574. from a separate editor accessory. You can also control your objects
  1575. directly from the mouse or joystick if required.
  1576.  
  1577.   The sheer versatility of the AMAL system has to be seen to be
  1578. believed.
  1579.  
  1580.  
  1581. AMAL principles
  1582. ===============
  1583. AMAL is effectively just a simple version of Basic which has been
  1584. carefully optimised for the maximum possible speed. As with Basic,
  1585. there are instructions for program control (Jump), making decisions
  1586. (If) and repeating sections of code in loops (For...Next). The real
  1587. punch comes when AMAL program is run. Not only are the commands
  1588. lightning fast but all AMAL programs are *compiled* before run-time.
  1589.  
  1590.   AMAL commands are entered using short keywords consisting of one or
  1591. more capital letters. Anything in lowercase is ignored completely. This
  1592. allows you to pad out your AMAL instructions into something more
  1593. readable. So the M command might be entered as Move or the L
  1594. instruction as Let.
  1595.  
  1596.   AMAL instructions can be separated by parctically any unused
  1597. characters including spaces. You can't however, use the colon ":" for
  1598. this purpose, as it's needed to define a label. We advise you to use a
  1599. semi-colon ";" to separate commands to avoid possible AMAL headaches.
  1600.  
  1601.   There are two ways of creating your AMAL programs. The first is to
  1602. produce your animation sequences with the AMAL accessory program and
  1603. save them into a memory bank or you can define your animations inside
  1604. AMOS Basic using the AMAL command. The general format of this function
  1605. is:
  1606.  
  1607.         AMAL n,a$
  1608.  
  1609. "n" is the identification number of your new AMAL program. As a default
  1610. all programs are assigned to the relevant hardware sprite. So the first
  1611. AMAL program controls sprite number one, the second sprite number two,
  1612. and so on. You can change this selection at any time using a separate
  1613. CHANNEL command. a$ is a string containing a list of AMAL instructions
  1614. to be performed in your program. Here's a simple example:
  1615.  
  1616.         Load "AMOS_DATA:Sprites/Monkey_right.abk"
  1617.         Get Sprite Palette
  1618.         Sprite 8,130,50,1                                                  177
  1619.         Amal 8,"S: M 300,200,100 ; M -300,200,100 J S"
  1620.         Amal On 8 : Rem Activate AMAL program number eight
  1621.         Direct
  1622.  
  1623. The program returns you straight back to direct mode with the DIRECT
  1624. command. Try typing a few Basic commands at this point. You can see the
  1625. movement pattern continues regardless, without interfering with the
  1626. rest of the AMOS system. Also note we have used sprite 8 to force the
  1627. use of a computed sprite. All computed sprites from 8 to 15 are
  1628. automatically assigned to the equivalent channel number by the AMAL
  1629. system. So there's no need for any special initialisation procedures.
  1630. Unless you wish to restrict the amount of hardware sprites it's safest
  1631. to stick to just computed sprites in your programs. Notice how we've
  1632. activated the AMAL program using the AMAL ON command. This has the
  1633. format:
  1634.  
  1635.         AMAL ON [prog]
  1636.  
  1637. "prog" is the number of a single AMAL program. If it's omitted, then
  1638. *all* your AMAL programs will be executed at once!
  1639.  
  1640.  
  1641. AMAL tutorial
  1642. =============
  1643. We'll now provide you with a guided tour of the AMAL system. This
  1644. allows you to slowly familiarise yourself with the mechanics of AMAL
  1645. programs, without having to worry about too many technical details.
  1646.  
  1647.   For the time being we'll be concentrating on sprite movements, but
  1648. the same principles can also be applied to bob or screen animations.
  1649.  
  1650.   Start off by loading some examples into memory. These can be found in
  1651. in the SPRITES folder on the AMOS data disc. To get a directory of
  1652. Sprite files type the following from the direct windows:
  1653.  
  1654.         Dir "AMOS_DATA:"
  1655.  
  1656. To load a sprite file, type a line like:
  1657.  
  1658.         Load "AMOS_DATA:Sprites/Octopus.abk"
  1659.  
  1660.  
  1661. Moving an object
  1662. ----------------
  1663. As you would expect from a dedicated animation language, AMAL allows
  1664. you to move your objects in a variety of different ways. The simplest
  1665. of these involves the use of the Move command.
  1666.  
  1667.  
  1668.  
  1669.                           Move (move object)
  1670.                           -
  1671. M w,h,n
  1672.  
  1673. The M command moves an object  w units to the right and h units down in
  1674. exactly n movement steps. If the coordinates of your subject were
  1675. (X,Y), then the object would progressively move to X+W,Y+H.
  1676.  
  1677.   Supposing you have a sprite at coordinates 100,100. The instruction
  1678. M 100,100,100  would move it to 200,200. The speed of this motion          178
  1679. depends on the number of movement steps. If n is large then each
  1680. individual sprite movement will be small and the sprite will move very
  1681. slowly. Conversely, a small value for n results in a large movement
  1682. steps which jerk the sprite across the screen at high speed. Here are
  1683. some examples of the Move command.
  1684.  
  1685.         Rem This moves an octopus down the screen using AMAL
  1686.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  1687.         Sprite 8,300,0,1
  1688.         Amal 8,"M 0,250,50" : Amal On 8 : Wait Key
  1689.  
  1690.         Rem Moves octopus down and across the screen
  1691.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  1692.         Sprite 10,150,150,1
  1693.         Amal 10,"M 300,-100,50" : Amal On 10 : Wait Key
  1694.  
  1695.         Rem Demonstrates multiple Move commands.
  1696.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  1697.         M$="Move 300,0,50 ; Move -300,0,50"
  1698.         Sprite 11,150,150,1
  1699.         Amal 11,M$ : Amal On 11 : Wait Key
  1700.  
  1701. Notice how we've expanded M to Move in above program. Since the letters
  1702. "ove" are in lower case, they will be ignored by the AMAL system.
  1703.  
  1704.   At first glance, Move is a powerful but unexciting little
  1705. instruction. It's ideal for moving objects such as missiles, but
  1706. otherwise it's pretty uninspiring.
  1707.  
  1708.   Actually nothing could be further from the truth. That's because the
  1709. parameters in the move instruction are not limited to simple numbers.
  1710. You can also use complex arithmetical expressions incorporating one of
  1711. a variety of useful AMAL functions. Example:
  1712.  
  1713.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  1714.         Sprite 12,150,150,1 : Amal 12,"Move XM-X,YM-Y,32"
  1715.         Amal On 12 : Wait Key
  1716.  
  1717. This smoothly moves computed sprite 12 to the current mouse position. X
  1718. and Y hold the coordinates of your sprite, and XM and YM are functions
  1719. returning the current coordinates of the mouse.
  1720.  
  1721.         It's possible to exploit this effect in games like Pac-Man to
  1722. make your objects chase the player's character. Example:
  1723.  
  1724.         Load Iff "AMOS_DATA:IFF/Frog_Screen.IFF",1
  1725.         Channel 1 To Screen Display 1                                      179
  1726.         Amal 1,"Move 0,-200,50 ; Move 0,200,50"
  1727.         Amal On 1 : Direct
  1728.  
  1729. Channel assigns an AMOS program to a particular object. We'll be
  1730. discussing this command in detail slightly later, but the basic format
  1731. is:
  1732.  
  1733.         CHANNEL p TO object n
  1734.  
  1735. "p" is the number of your AMAL program. Allowable values range from 0
  1736. to 63, although only the first 16 of these programs can be performed
  1737. using interrupts.
  1738.  
  1739.   "object" specifies the type of object you with to control with your
  1740. AMAL program. This is indicated using one of the following statements:
  1741.  
  1742.         Sprite          (values >7 refer to computed sprites)
  1743.         Bob             (blitter object)
  1744.         Screen Display  (used to move the screen display)
  1745.         Screen Offset   (Hardware scrolling)
  1746.         Screen Size     (Changes the screen size using interrupts)
  1747.         Rainbow         (Animates a rainbow effect)
  1748.  
  1749. "n" is the number of the object to be animated. This object needs to be
  1750. subsequently defined using the SPRITE, BOB or SCREEN open instructions.
  1751.  
  1752.  
  1753. Animation
  1754. ---------
  1755.  
  1756.  
  1757.                        Anim (animate an object)
  1758.                        -
  1759. A n,(image,delay)(image,delay)...
  1760.  
  1761. The Anim instruction cycles an object through a sequence of images,
  1762. producing a smotth animation effect. "n" is the number of times the
  1763. animation cycle is to be repeated. A value of zero for this parameter
  1764. will perform the animation continuously.
  1765.  
  1766.   "image" sprcifies the number of an image to be used for each frame of
  1767. your animation. "delay" determines the length of time this image is to
  1768. be displayed on the screen, measured in units of a 50th of a second.
  1769. Example:
  1770.  
  1771.         Load "AMOS_DATA:Sprites/Monkey_right.abk" : Get Sprite Palette
  1772.         Sprite 9,150,50,11
  1773.         M$="Anim 12, (1,4)(2,4)(3,4)(4,4)(5,4)(6,4) ;"                     180
  1774.         M$=M$+"Move 300,150,150 ; Move -300,-150,75"
  1775.         Amal 9,M$
  1776.         Amal On 9
  1777.         Direct
  1778.  
  1779. This program combines a sprite movement with an animation. Notice how
  1780. we've separated the commands with a semi-colon. This ensures that the
  1781. two operations are totally independent of each other. Once the
  1782. animation sequence has been defined, AMAL will immediatly jump to the
  1783. next instruction, and the animation will begin.
  1784.  
  1785.   It's important to realize that Anim only works in conjunction with
  1786. sprites and bobs. So it's not possible to animate entire screen with
  1787. this command.
  1788.  
  1789.  
  1790. Simple Loops
  1791. ------------
  1792.  
  1793.  
  1794.                    Jump (redirects an AMAL program)
  1795.                    -
  1796. J label
  1797.  
  1798. Jump provides a simple way of moving from one part of an AMAL program
  1799. to another. "label" is the target of your jump, and must have been
  1800. defined elsewhere in your current program. All AMAL labels are defined
  1801. using a single uppercase followed by a colon. like instructions, you
  1802. can pad them out with lower case to improve readability.
  1803.  
  1804.   Remember that each label is deinfed using just a *single* letter. So
  1805. "S:" and "Swoop:" refer to the same label! If you attempt to define two
  1806. labels starting with an identical letter, you'll be presented with a
  1807. "label already defined in animation string" error.
  1808.  
  1809.         Each AMAL program can have its own unique set of labels. It's
  1810. perfectly acceptable to use the identical labels in several different
  1811. programs. Example:
  1812.  
  1813.        Load "AMOS_DATA:Sprites/Octopus.abk"
  1814.        Get Sprite Palette
  1815.        For S=8 to 20 Step 2 : Rem Set up 7 computed sprites
  1816.         Sprite S,200,(S-7)*13+40,1
  1817.        Next S
  1818.        Rem : Now let's create seven AMAL programs
  1819.        For S=1 to 7
  1820.         Channel S To Sprite 6+(S*2)
  1821.         M$="Anim 0,(1,2)(2,2)(3,2)(4,2) ; Label: Move "+Str$(S*2)"+,0,7 ;"
  1822.         Amal S,M$
  1823.        Next S
  1824.        Rem Okay, now animate it all!
  1825.        Amal On : Direct
  1826.  
  1827. Since AMAL commands are performed using interrupts, infinite lopos         181
  1828. could be disasterous. So a special counter is automatically kept of the
  1829. number of jumps in your program. When the counter exceeds ten, any
  1830. further jumps will be totally ignored by the AMAL system.
  1831.  
  1832.   NOTE: if you rely on this system, and allow your programs to loop
  1833. continually, uou'll waste a great deal of the Amiga's computer power.
  1834. In practice, it's much more effecient to limit yourself to just a
  1835. single jump per VBL. This can be achieved by adding a simple PAUSE
  1836. comand before each Jump in your program. See PAUSE for more details.
  1837.  
  1838.  
  1839. Variables and expressions
  1840. -------------------------
  1841.  
  1842.  
  1843.                   Let (assigns a value to a register)
  1844.                   -
  1845. L register=expression
  1846.  
  1847. The L instruction assigns a value to an AMAL register. The action is
  1848. very similar to normal Basic, except that all expressions are evaluated
  1849. strictly from left to right.
  1850.  
  1851.   Registers are integer variables used to hold the intermediate values
  1852. in your AMAL programs. Allowable numbers range between -32768 to +32768.
  1853. There are three basic types of register:
  1854.  
  1855.   Internal registers
  1856.   - - - - - - - - -
  1857.   Every AMAL program has its own set of 10 internal registers. The
  1858.   names of these registers start with the letter R, followed by one of
  1859.   the digits from 0 to 9 (R0-R9). Internal registers are like the local
  1860.   variables inside an AMOS Basic procedure.
  1861.  
  1862.   External registers
  1863.   - - - - - - - - -
  1864.   Ecternal registers are rather different because they retain their
  1865.   values between separate AMAL programs. This allows you to use these
  1866.   registers to pass information between several AMAL routines. AMAL
  1867.   provides you with up to 26 external registers, with names ranging
  1868.   from RA to RZ. The contents of any internal or external register can
  1869.   be accessed directly from your Basic program using the AMREG function.
  1870.  
  1871.   Special registers                                                        182
  1872.   - - - - - - - - -
  1873.   Special registers are a set of three values which determine the
  1874.   status of your object. X,Y contain the coordinates of your object. By
  1875.   changing these registers you can move your object around on the
  1876.   screen. Example:
  1877.  
  1878.         Load "AMOS_DATA:Sprites/Frog_Sprites.abk" : Channel 1 To Bob 1
  1879.         Flash Off : Get Sprite Palette : Bob 1,0,0,1
  1880.         Amal 1,"Loop: Let X=X+1 ; Let Y=Y+1; Pause; Jump Loop"
  1881.         Amal On 1 : Direct
  1882.  
  1883. "A" stores the number of the image which is displayed by a sprite or
  1884. bob. You can alter this value to generate your own animation sequences
  1885. like so:
  1886.  
  1887.         Load "AMOS_DATA:Sprites/Frog_Sprites.abk" : Get Sprite Palette
  1888.         Flash Off : Channel 2 To Bob 1 : Bob 1,300,100,1
  1889.         M$="Loop: Let A=A+1 ; "
  1890.         M$=M$+"For R0=1 To 5 ; Next R0 ; Jump Loop"
  1891.         Amal 2,M$
  1892.         Amal On 2 : Direct
  1893.  
  1894. The For To Next lop will be explained in more detail below. It is used
  1895. here to slow down each change to Bob 1's image. When the "Next" of the
  1896. loop is executed, AMAL won't continue until a vertical blank has
  1897. occurred. Also note the use of ";" to separate the AMAL instructions -
  1898. although a space " " will serve just as well.
  1899.  
  1900.  
  1901. Operators
  1902. ---------
  1903. AMAL expressions can include all the normal arithmetic operations,
  1904. except MOD. You can also use the following logical operatoins in your
  1905. calculations:
  1906.  
  1907.         &       Logical AND
  1908.         |       Logical OR
  1909.  
  1910. Note that it's not possible to change the order of evaluation using
  1911. brackets "()" as this would slow down your calculations considerably
  1912. and thus reduce the allowable time in the interrupt. Type the following
  1913. example:
  1914.  
  1915.         Load "AMOS_DATA:Sprites/Octopus.abk" : Hide
  1916.         Get Sprite Palette
  1917.         Sprite 8,X Mouse,Y Mouse,1
  1918.         Amal 8,"Loop: Let X=XM ; Let Y=YM ; Pause ; Jump Loop"
  1919.         Amal On 8
  1920.  
  1921.         Load "AMOS_DATA:Sprites/Octopus.abk" : Hide
  1922.         Get Sprite Palette
  1923.         Sprite 8,X Mouse,Y Mouse,1
  1924.         Amal 8,"Anim 0,(1,4)(2,4)(3,4)(4,4) ; Loop: Let X=XM ; Let
  1925.                                           Y=YM ; Pause ; Jump Loop"
  1926.         Amal On
  1927.  
  1928. The above examples effectively mimic the CHANGE MOUSE command. However
  1929. this system is much more powerful as you can easily move bobs, computed
  1930. sprites, or even screens using exactly the same technique.
  1931.  
  1932.  
  1933. Making decisions                                                           183
  1934. ----------------
  1935.  
  1936.  
  1937.                    If (branch within an AMAL string)
  1938.  
  1939. If test Jump L
  1940.  
  1941. This instruction allows you to perform simple tests in your AMAL
  1942. programs. If the expression test is -1 (true) the program will jump to
  1943. label L, otherwise AMAL will immediately progress to the next
  1944. instruction. Note that unlike it's equivalent, you're limited to a
  1945. single jump operation after the test.
  1946.  
  1947.   It's common practice to pad out this instruction with lowercase
  1948. commands like "then" or "else". This makes the action of the command
  1949. rather more obvious. Here's an example:
  1950.  
  1951.         If X>100 then Jump Label else Let X=X+1
  1952.         -             -    -          -
  1953. "test" can be any logical expression you like, and may include:
  1954.  
  1955.         <>  Not equals
  1956.         <   Less than
  1957.         >   Greater than
  1958.         =   Equals
  1959.  
  1960. Example:
  1961.  
  1962.         Load "AMOS_DATA:Sprits/Octopus.abk"
  1963.         Get Sprite Palette
  1964.         Sprite 8,130,50,1
  1965.         C$="Main: If XM>100 Jump Test: "
  1966.         C$=C$+"Let X=XM "
  1967.         C$=C$+"Test: If YM>100 Jump Main "
  1968.         C$=C$+"Let Y=YM Jump Main"
  1969.         Amal 8,C$ : Amal On : Direct
  1970.  
  1971. WARNING! Don't try to combine several tests into a single AMAL
  1972. expression using "&" or "|". Since expressions are evaluated from left
  1973. to right, this will generate an error. Take the expression:
  1974. X>100|Y>100. This is intended to check whether X>100 OR Y>100. In
  1975. practice, the expression will be evaluated in the following order:
  1976.  
  1977.         X>100   May be TRUE or FALSE                                       184
  1978.         |Y      OR result with Y
  1979.         >100    Check if (Y>100|Y)>100)
  1980.  
  1981. The result from the above expression will obviously be no relation to
  1982. the expected value. Technically-minded users can avoid this problem by
  1983. using boolean algebra. First assign each test to an single AMAL
  1984. register like so:
  1985.  
  1986.         Let R0=X>100; Let R1=Y>100
  1987.  
  1988. Now combine these tests into a single expression using | and & and use
  1989. it directly in your If statement.
  1990.  
  1991.         If R0 | R1 Jump L ...
  1992.  
  1993. This may look a little crazy, but it works beautifully in practice.
  1994.  
  1995.  
  1996.                     For To Next (loop within AMAL)
  1997.                     -   -  -
  1998. For reg=start To end
  1999.   :   :
  2000. Next reg                      This implements a standard FOR...NEXT
  2001.                               loop which is almost identical to its
  2002. Basic equivalent. These loops can be exploited in your programs to move
  2003. objects in complex visual patterns. "reg" may be any normal AMAL
  2004. register (R0-R9 or RA-RZ). However you can't use special registers for
  2005. this purpose.
  2006.  
  2007.   As with Basic, the register after the Next must match with the
  2008. counter you specified in the For, otherwise you'll get an AMAL syntax
  2009. error. Also note that the step size is always set to one. Additionally,
  2010. it's possible to "nest" any number of loops inside each other.
  2011.  
  2012.   Note that each animation channel will only perform a single loop per
  2013. VBL. This synchronizes the effects of your loops with the screen
  2014. display, and avoids the need to add an explicit Pause command before
  2015. each Next.
  2016.  
  2017.  
  2018. Generating an attack wave for a game
  2019. ------------------------------------
  2020. These lopos can be used to create some quite complex movement patterns.
  2021. The easiest type of motion is in a straight line. This can be generated
  2022. using a single For...Next loop like so:
  2023.  
  2024.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  2025.         Sprite 8,130,60,1
  2026.         C$=For R0=1 To 320 ; Let X=X+1 ; Next R0" : Rem Move sprite
  2027.         Amal 8,C$ : Amal On 8 : Direct
  2028.  
  2029. You can now expand this program to sweep the object back and forth
  2030. across the screen.
  2031.  
  2032.         Load "AMOS_SATA:Sprites/Octopus.abk" : Get Sprite Palette
  2033.         Sprite 8,130,60,1
  2034.         C$="Loop: For R0=1 To 320 ; Let X=X+1 ; Next R0 ;"                 185
  2035.         C$=C$+" For R0=1 To 320 ; Let X=X-1 ; Next R0 ; Jump Loop"
  2036.         Amal 8,C$ : Amal On 8 : Direct
  2037.  
  2038. The first loop moves the object from left to right, and the second from
  2039. right to left. So far the pattern has been restricted to just
  2040. horizontal movements. In order to create a realistic attack wave, it's
  2041. necessary to incorporate a vertical component to this motion as well.
  2042. This can be achieved by enclosing your program with yet another loop.
  2043.  
  2044.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  2045.         Sprite 8,130,60,1 : C$=For R1=0 To 10 ;"
  2046.         C$=C$+"For R0=1 To 320 ; Let X=X+1 ; Next R0 ; "
  2047.         C$=C$+"Let Y=Y+8 ; "
  2048.         C$=C$+"For R0=1 To 320 ; Let X=X-1 ; Next R0 ; "
  2049.         C$=C$+"Let Y=Y+8 ; Next R1"
  2050.         Amal 8,C$ : Amal On 8
  2051.  
  2052. The above programs generates a smooth but quite basic attack pattern. A
  2053. further demonstration can be found in EXAMPLE 14.1 in the MANUAL
  2054. folder.
  2055.  
  2056.  
  2057. Recording a complex movement sequence
  2058. -------------------------------------
  2059.  
  2060.  
  2061.                                  PLay
  2062.                                  --
  2063. PLay path
  2064.  
  2065. If you've looked at the smooth attack waves in a modern arcade game,
  2066. and thought them forever beyond your reach, think again. The AMAL Play
  2067. command allows you freely animate your objects through practically any
  2068. sequence of movements you can imagine. It works by playing a previously
  2069. defined movement pattern stored in the AMAL memory bank.
  2070.  
  2071.   These patterns are created from the AMAL accessory on the AMOS
  2072. program disc. This simply records a sequence of mouse movements and
  2073. enters them directly into the amal memory bank. Once you've created
  2074. your patterns in this way, you can effortlessly assign them to any
  2075. object on the screen, reproducing your original patterns perfectly.
  2076. Both the speed and direction of your movement can be changed at any
  2077. time from your AMOS Basic program.
  2078.  
  2079.   The first time AMAL encounters a Play command, it checks the AMAL
  2080. bank to find the recorded movement you specified using the "path"
  2081. parameter. "path" is simply a number ranging from one to the maximum
  2082. number of patterns in the bank. If a problem crops up during this
  2083. phase, AMAL will abort the play instruction completely, and will skip
  2084. to the next instruction in your animation string.
  2085.  
  2086.   After the pattern has been initialised, register R0 will be loaded
  2087. with the tempo of the movement. This determines the time interval
  2088. between each individual movement step. All timings are measured in
  2089. units of a 50th of a second. By changing this register within your AMAL
  2090. program, you can speed up or slow down your object movements
  2091. accordingly.
  2092.  
  2093.   Note that each movement step is *added* to the current coordinates of
  2094. your object. So if an object is subsequently moved using the Sprite or
  2095. Bob instructions, it will continue its manoeuvres unaffected, starting
  2096. from the new screen position. It's therefore possible to animate dozens
  2097. of different objects on the screen using a single sequence of
  2098. movements.
  2099.  
  2100.   Register R1 now contains the flag which sets the direction of your       186
  2101. movements. There are three possible situations:
  2102.  
  2103.     *  R1>0   Forward
  2104.  
  2105. A value of one for R1 specifies that the movement pattern will be
  2106. replayed from start to finish, in exactly the order it was created
  2107. (this is the default).
  2108.  
  2109.     *  R1=0   Backward
  2110.  
  2111. Many animation sequences require your objects to move back and forth
  2112. across the screen in a complex pattern. To change direction, simply
  2113. load R1 with a zero. Your object will now turn around and execute your
  2114. original movement steps in reverse.
  2115.  
  2116.     *  R1=-1  Exit
  2117.  
  2118. If a collision has been detected from your AMOS program, you'll need to
  2119. stop your object completely, and generate an explosion effect. This can
  2120. be accomplished by setting R1 to a value of minus one. AMAL will now
  2121. abort the play instruction, and immediately jump to the next
  2122. instruction in your animation sequence.
  2123.  
  2124.   The clever thing about these registers is that they can be changed
  2125. directly from AMOS Basic. This lets you control your movement patterns
  2126. directly from within your main program. There's even a special AMPLAY
  2127. instruction to make things easier for you.
  2128.  
  2129.   The PLay comand is perfect for controlling the aliens in an arcade
  2130. game. In fact, it's the single most powerful instruction in AMAL.
  2131.  
  2132.  
  2133.  
  2134.                       AMAL (call an AMAL program)
  2135.  
  2136. AMAL n,a$
  2137. AMAL n,p
  2138. AMAL n,a$ to address          The AMAL command assigns an AMAL program
  2139.                               to an animation channel. This program can
  2140.     be taken either from a string in a$ or directly from the AMAL bank.
  2141.  
  2142.   The first version of the instruction loads your program from the
  2143. string a$ and assigns it to channel n. a$ can contain any list of AMAL
  2144. instructions. Alternatively you can load your program from a memory
  2145. bank stored in bank number 4.
  2146.  
  2147.   n is the number of an animation channel ranging from 0 to 63. Each
  2148. AMOS channel can be independently assigned to either a bob, a sprite or
  2149. a screen.
  2150.  
  2151.   Only the first 16 AMAL programs can be performed using interrupts. In
  2152. order to exceed this limit you need execute your programs directly from
  2153. Basic using the SYNCHRO command.
  2154.  
  2155.   The final version of the AMAL insturction is provided for advanced
  2156. users. Instead of moving an actual object, this simply copies the
  2157. contents of registers X,Y and A into a specific area of memory. You can
  2158. now use this information directly in your own Basic routines. It's         187
  2159. therefore possible to exploit the AMAL system to animate anything from
  2160. a Block to a character. The format is:
  2161.  
  2162.         AMAL n,a$ To address
  2163.  
  2164. "address" must be EVEN and must point to safe region of memory,
  2165. preferably in an AMOS string or a memory bank. Every time your AMAL
  2166. program is executed (50 times per second), the following values will be
  2167. written into this memory area:
  2168.  
  2169.      Location     Effect
  2170.      --------     ------
  2171.      Address      Bit 0 is set to 1 if the X has changed
  2172.                   Bit 1 indicates that Y has been altered
  2173.                   Bit 2 will be set if the image (A) has changed since
  2174.                         the last interrupt.
  2175.      Address+2    Is a *word* containing the latest value of X
  2176.      Address+4    Holds the current value of Y
  2177.      Address+6    Stores the value of A
  2178.  
  2179. These values can be accessed from your program using a simple DEEK.
  2180. NOTE: This option totally overrides any previous CHANNEL assignments.
  2181.  
  2182.  
  2183. AMAL commands
  2184. =============
  2185. Here is a full list of the available amal commands:
  2186.  
  2187. M (Move)        Move deltaX, deltaY, steps
  2188. A (Anim)        Anim cycles,(image,delay)(image,delay)...
  2189. L (Let)         Let reg=exp                                                188
  2190. J (Jump)        Jump L
  2191. I (If)          If exp Jump L
  2192. For To Next     For Reg=start To end ...Next Reg
  2193. PL (PLay)       PLay path                                                  189
  2194. P (Pause)       Pause
  2195.  
  2196. AU (AUtotest)   AU (list of tests)             See the Autotest System     190
  2197.  
  2198. X (eXit)        eXit          Exits from an AUtotest and re-enters the
  2199.                               current AMAL program.
  2200.  
  2201. W (Wait)        Wait          Freezes your AMAL program and only
  2202.                               executes the AUtotest.
  2203.  
  2204. O (On)          On            Activates the main program after a Wait.
  2205.  
  2206. D (Direct)      Direct        Sets the section of the main program
  2207.                               to be executed after an autotest.
  2208.  
  2209. AMAL functions                                                             191
  2210. ==============
  2211.  
  2212. =XM          Returns the X coordinate of the mouse
  2213. =YM          Returns the Y coordinate of the mouse
  2214. =K1          Status of left mouse key (-1, if pressed, otherwise 0)
  2215. =K2          Status of right mouse key
  2216. =J0          Test right joystick. Result in bit-map.
  2217. =J1          Test left joystick. See the JOY command.
  2218.  
  2219. =Z(n)        Random number. Returns a random number between -32767
  2220.              to 32768. This number can be limited to a specific
  2221.              range using the bit-mask n. A logical AND operation
  2222.              is performed between the bit mask n and the random
  2223.              number to generate the final result. So setting n to
  2224.              a value of 255 will ensure that the numbers will be
  2225.              returned in the range 0 to 255. Since this function has
  2226.              been optimized for speed, the number returned isn't
  2227.              totally random. If you need really random numbers, you
  2228.              would be better to generate your values using Basic's
  2229.              RND and then load them into an external AMAL register
  2230.              with the AMREG function.
  2231.  
  2232. =XH(s,x)     Converts a screen x coordinate into a hardware coordinate.    192
  2233. =YH(s,y)     Converts a screen y coordinate into hardware format.
  2234. =XS(s,x)     Hardware to screen conversion
  2235. =YS(s,y)     Hardware to screen conversion
  2236.  
  2237. =BC(n,s,e)   Check for collisions between bobs. BC is identical to the
  2238.              equivalent AMOS Basic BOB COL instruction. It checks bob
  2239.              number n for collisions between bobs s to e. If a
  2240.              collision has been detected, then BC will return a value
  2241.              of -1, otherwise 0. This instruction may NOT be performed
  2242.              within an iterrupt. So it's only available when you are
  2243.              executing your AMAL routines directly from Basic with the
  2244.              SYNCHRO instruction.
  2245.  
  2246. =SC(n,s,e)   This is equivalent to the SPRITE COL function. Like BC
  2247.              function, it's only allows in conjuction with the SYNCHRO
  2248.              instruction.
  2249.  
  2250. =V(v)        VU-meter. The VU function samples one of the sound
  2251.              channels and returns the intensity of the current voice.
  2252.              This is a number in the range 0-255. You can use this
  2253.              information to animate your objects in time to the music.
  2254.              An example of this can be found in EXAMPLE 14.3. Also see
  2255.              the VUMETER function from AMOS Basic
  2256.  
  2257.  
  2258. Controlling AMAL from Basic                                                193
  2259. ===========================
  2260.  
  2261.  
  2262.                AMAL ON/OFF (start/stop an AMAL program)
  2263.  
  2264. AMAL ON [n]
  2265.  
  2266. Once you've defined your AMAL program you need to execute it using the
  2267. AMAL ON command. This activates the AMAL system and starts your
  2268. programs from the first instruction.
  2269.  
  2270.   AMAL ON activates all your programs. The optional parameter n allows
  2271. you start just one routine at a time.
  2272.  
  2273.         AMAL OFF [n]
  2274.  
  2275. Stops one or all AMAL programs from executing. These programs are
  2276. erased from meomry. They can only be restarted by redefining them again
  2277. using the AMAL instruction.
  2278.  
  2279.  
  2280.  
  2281.                     AMAL FREEZE (temporarily freeze
  2282.                            an amal program)
  2283. AMAL FREEZE [n]
  2284.  
  2285. Stops one or more AMAL programs for running. Your programs can be
  2286. restarted at any time using a simple call to AMAL ON. Note that this
  2287. instruction should always be used to stop AMAL before a command such as
  2288. DIR is executed, otherwise problems with timing can cause visual
  2289. mishaps.
  2290.  
  2291.  
  2292.  
  2293.                      =AMREG= (get the value of an
  2294.                         external AMAL register)
  2295.  
  2296. r=AMGER(n, [channel])
  2297. AMREG(n, [channel])=expression
  2298.  
  2299. The AMREG function allows you to access the contents of internal and
  2300. external AMAL register directly from within your Basic program.
  2301.  
  2302.   "n" is the number of the register. Possible values range from 0 to 25
  2303. with zero representing register RA and twenty-five denoting RZ.
  2304.  
  2305.   By using the optional "channel" parameter you can reference any AMAL
  2306. internal register. In this mode "n" ranges between 0 and 9 representing
  2307. R0 to R9.
  2308.  
  2309.   The following examples shows how it is possible to retrieve a
  2310. sprite's current X-position from Basic:
  2311.  
  2312.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  2313.         Channel 1 To Sprite 8 : Sprite 8,100,100,1
  2314.         A$="Loop: Let RX=X+1; Let X=RX; Pause; Jump Loop"
  2315.         Amal 1,A$ : Amal On : Curs Off
  2316.         Do
  2317.           Locate 0,0
  2318.           Z=Asc("X")-65 : Rem Note the use of ASC to get the register #
  2319.           Print Amreg(Asc("X")-65)
  2320.         Loop
  2321.  
  2322.  
  2323.  
  2324.                      AMPLAY (control an animation                          194
  2325.                           produced with PLay)
  2326.  
  2327. AMPLAY tempo,direction [start TO end])
  2328.  
  2329. Any movement sequences you've produced using the AMAL PL command are
  2330. controlled through the internal registers R0 and R1. Each object will
  2331. be assigned it's own unique set of AMAL registers. So if you're
  2332. animating several objects, you'll often need to load a number of these
  2333. registers with exactly the same values.
  2334.  
  2335.   Although this can be achieved using the standard AMREG function, it
  2336. would obviously be much easier if there was a single instruction which
  2337. allowed you to change R0 and R1 for a whole batch of objects at a time.
  2338. That's the purpose of the AMPLAY command.
  2339.  
  2340.   AMPLAY takes the "tempo" and "direction" of your movements, and loads
  2341. them into the registers R0 and R1 in the selected channels.
  2342.  
  2343.   "tempo" controls the speed of your object on the screen. It sets a
  2344. delay (in 50ths of a second) between each successive movement step.
  2345.  
  2346.   "direction" changes the direction of the motion. Here's a list of the
  2347. various different options.:
  2348.  
  2349.      Value Direction
  2350.      ----- ---------
  2351.       >0   Move the selected object in the original movement direction.
  2352.        0   Reverses the motion and moves the object backwards
  2353.       -1   Aborts movement pattern and jumps to the following
  2354.            instruction in your AMAL animation sequence.
  2355.  
  2356. As a default, this instruction will affect all current animation
  2357. channels. This can be changed by adding some explicit "start" and "end"
  2358. points to the command. "start" is the channel number of the first
  2359. object to be adjusted. "end" holds the channel number assigned to the
  2360. last object in your list. Note that either the "tempo" or the
  2361. "direction" can be omitted as required. Examples:
  2362.  
  2363.         Amplay ,0         : Rem reverse your objects
  2364.         Amplay 2,         : Rem Slow down your movement patterns
  2365.         Amplay ,-1 3 To 6 : Rem stop movements on channels 3,4,5 and 6.
  2366.  
  2367.  
  2368.  
  2369.                      =CHANAN (test AMAL animation)                         195
  2370.  
  2371. s=CHANAN(channel)
  2372.  
  2373. This is a simple function which checks the status of an AMAL animation
  2374. sequence and returns -1 (true) if it's currently active or 0 if the
  2375. animation is complete. "channel" holds the number of the channel to be
  2376. tested.
  2377.  
  2378.  
  2379.  
  2380.                    =CHANMV (checks whether an object
  2381.                            is still moving)
  2382. s=CHANMV(channel)
  2383.  
  2384. Returns a value of -1 if the object assigned to "channel" is currently
  2385. moving, otherwise 0 (false).
  2386.  
  2387.   This command can be used in conjunction with the AMAL Move
  2388. instruction to check whether a movement sequence has "run out" of
  2389. steps. You can now restart the sequence at the new position with an
  2390. appropriate movement string if required. Example:
  2391.  
  2392.         Load "AMOS_DATA:Sprites/Monkey_right.abk" : Get Sprite Palette
  2393.         Sprite 9,150,50,11
  2394.         M$=Move 300,150,150; Move -300,-150,75"
  2395.         Amal 9,M$ : Amal On
  2396.         While Chanmv(9)
  2397.         Wend
  2398.         Print "Movement complete"
  2399.  
  2400.  
  2401.  
  2402. AMAL errors
  2403. ===========
  2404.  
  2405.  
  2406.               =AMALERR (return the position of an error)
  2407.  
  2408. p=AMALERR
  2409.  
  2410. Returns the position in the current animation string where an error has
  2411. occurred. Careful inspection of this string will allow you to quickly
  2412. correct your mistakes. Example:
  2413.  
  2414.         Load "AMOS_DATA:Sprites/Octopus.abk"
  2415.         Sprite 8,100,100,1
  2416.         A$="L: IF X=300 then Jump L else X=X+1; Jump L"
  2417.         Amal 8,A$
  2418.  
  2419. This program will generate a syntax error because IF will be
  2420. interpreted as the two instructions I and F. To find the position in
  2421. the animation string of this error, type the following instruction from
  2422. the direct window.
  2423.  
  2424.         Print Mid$(A$,Amalerr,Amaller+5)
  2425.  
  2426.  
  2427. Error messages                                                             196
  2428. --------------
  2429. If you make a mistake in one of your AMAL programs, AMOS will exit back
  2430. to Basic with an appropriate error message. Here's a full list of the
  2431. errors which can be generated by this system, along with an explanation
  2432. of their most likely causes.
  2433.  
  2434.  Bank not reserved: This error is caused if you attempt to call the
  2435.                     PLay instruction without first loading a bank
  2436.          containing the movement data into memory. This should be
  2437.          created with the AMAL accessory program. If you're not using
  2438.          PLay at all then check that you've correctly separated any
  2439.          Pause and Let instructions.
  2440.  
  2441.  Insturction only valid in Autotest: You've inadvertently called either
  2442.                                      the Direct or the eXit
  2443.          instructions from your main AMAL program.
  2444.  
  2445.  Illegal instruction in Autotest: Autotest may only be used in
  2446.                                   conjunction with a limited range of
  2447.          AMAL commands. It's not possible to move or animate our
  2448.          objects in any way inside an autotest. So check for erroneous
  2449.          commands like Move, Anim or For...Next.
  2450.  
  2451.  Jump To/Within Autotest in animation string: The commands inside an
  2452.                                               autotest function are
  2453.          completely separate from your main AMAL program. So AMAL does
  2454.          not allow you to jump directly inside an AUtotest procedure.
  2455.          To leave an autotest, and return to your main AMAL program you
  2456.          must use either eXit or Direct.
  2457.  
  2458.  Label already defined in animation string: You've attempted to define
  2459.                                             the same label twice in
  2460.          your AMAL program. All AMAL labels consist of just a single
  2461.          CAPITAL letter. So "Test" and "Total" are just different
  2462.          versions of the same label (T). This error is also generated
  2463.          if you have accidentally separated two instructions by a ":"
  2464.          (colon). Use a semi-colon instead.
  2465.  
  2466.  Label not defined in animation string: This error is generated when
  2467.                                         you try to jump to a label
  2468.          which doesn't currently exist in your animation string.
  2469.  
  2470.  Next without For in animation string: Like it's Basic equivalent each
  2471.                                        For command should be matched
  2472.          by a corresponding Next statement. Check any nested loops for
  2473.          an spurious Next command.
  2474.  
  2475.  Syntax error in animation string: You've made a typing mistake in one
  2476.                                    of your animation strings. It's easy
  2477.          to cause this error by accidentally entering an AMAL
  2478.          instruction in full, just like its Basic equivalent.
  2479.  
  2480.  
  2481. Animation channels                                                         197
  2482. ==================
  2483. Amos allows you to execute up to 64 different AMAL programs
  2484. simultaneously. Each program is assigned to a specific animation
  2485. channel.
  2486.  
  2487.   Only the first 16 channels can be performed using interrupts. If you
  2488. need to animate more objects you'll have to turn off the interrupts
  2489. using SYNCHRO OFF. You can now execute the AMAL programs step by step
  2490. using an explicit call to the SYNCHRO command in yur main program loop.
  2491. As a default, all interrupt channels are assigned to the relevant
  2492. hardware sprite.
  2493.  
  2494.  
  2495.  
  2496.              CHANNEL (assign an object to an AMAL channel)
  2497.  
  2498. CHANNEL n TO object s
  2499.  
  2500. The CHANNEL command assigns an animation channel to a particular screen
  2501. related "object". In AMAL, you're not restricted to a single channel
  2502. per object. Any single screen object can be safely animated with
  2503. several channels if required. There are various different forms of this
  2504. instruction.
  2505.  
  2506.  
  2507. Animating a computed sprite
  2508. ---------------------------
  2509.  
  2510. CHANNEL n TO SPRITE s
  2511.  
  2512. This assigns sprite number s to channel n. As a default, channels 0-7
  2513. are automatically allocated to the equivalent hardware sprite, and 8-15
  2514. are reserved for the appropriate computed sprites.
  2515.  
  2516.   In order to animate the computed sprites from 16 onwards, you'll need
  2517. to allocate them directly to an animation channel with the CHANNEL
  2518. command. As normal , sprite numbers from 8 to 63 specify a computed
  2519. sprite rather than a single hardware sprite. For example;
  2520.  
  2521.         Channel 5 To Sprite 8 : Rem Animates Computed sprite 8 using
  2522.                                     Channel 5.
  2523.  
  2524. The X,Y  registers in your AMAL program now refer to the hardware
  2525. coordinates of the selected sprite. Similarly the current sprite image
  2526. is held in register A.
  2527.  
  2528.  
  2529. Animating a blitter object
  2530. --------------------------
  2531.  
  2532. CHANNEL n TO BOB b
  2533.  
  2534. Allocates blitter object b to animation channel n. This object will be
  2535. treated in an identical way to the equivalent hardware sprite. The only
  2536. difference is that registers X and Y now contain the position of your
  2537. bob in *screen* coordinates.
  2538.  
  2539.   Note that if you've activated screen switching with the DOUBLE BUFFER
  2540. command, this will be automatically used for all bob animations.
  2541.  
  2542.  
  2543. Moving a screen                                                            198
  2544. ---------------
  2545. AMOS Basic allows you to freely position the current screen anywhere on
  2546. your TV display. Normally this is controlled with the SCREEN DISPLAY
  2547. instruction. However, sometimes it's useful to be able to move the
  2548. screen using interrupts.
  2549.  
  2550. CHANNEL n TO SCREEN DISPLAY d
  2551.  
  2552. This sets the channel n to screen number d. Screen d can be defined
  2553. anywhere in your program. You'll only get an error if the screen hasn't
  2554. been opened when you start your animation.
  2555.  
  2556.   The X and Y variables in AMAL now hold the position of your screen in
  2557. hardware coordinates. Register A is *not* used by this option and you
  2558. can't animate screens using Anim. Otherwise all standard AMAL
  2559. instructions can be performed as normal. So you can easily use this
  2560. system to "bounce" the picture aroud the display. Examples:
  2561.  
  2562.         Load Iff "AMOS_DATA:IFF/Frog_screen.IFF",1
  2563.         Channel 0 To Screen Display 1
  2564.         Amal 0,"Loop: Move 0,200,100 ; Move 0,-200,100 ; Jump Loop"
  2565.         Amal On 0 : Direct
  2566.  
  2567.         Load Iff "AMOS_DATA:IFF/Frog_screen.IFF",1
  2568.         Channel 0 To Screen Display 1
  2569.         Rem Screen can only be displayed at certain positions in the X
  2570.         Amal 0,"Loop: Let X=XM; Let Y=YM; Pause; Jump Loop"
  2571.         Amal On : Direct
  2572.  
  2573. For a further example of this technique, load EXAMPLE 14.4. This
  2574. demonstrates how the SCREEN DISPLAY can be used in conjunction with the
  2575. menu commands to slide the menu screen up and down your display. It's
  2576. similar to the display system found in Magnetic Scrolls' excellent
  2577. series of adventures.
  2578.  
  2579.  
  2580. Hardware scrolling
  2581. ------------------
  2582. Although hardware scrolling can be performed using AMOS Basic's SCREEN
  2583. OFFSET command, it's often easiest to animate your screens using AMAL
  2584. instead as this generates a much smoother effect.
  2585.  
  2586. CHANNEL n TO SCREEN OFFSET d
  2587.  
  2588. This assigns AMAL program number n to a screen d, for the purpose of
  2589. hardware scrolling. The X and Y registers now refer to the section of
  2590. the screen which is to be displayed through your TV. Changing these
  2591. registers will scroll the visible screen area around the display.
  2592. Here's an example:
  2593.  
  2594.         Screen Open 0,320,500,32,lowres : Rem Open an extra tall screen
  2595.         Screen Display 0,,45,320,250
  2596.         Load Iff "AMOS_DATA:IFF/Magic_screen.IFF"
  2597.         Screen copy 0,0,0,320,250 To 0,0,251
  2598.         Screen 0 : Flash Off : Get Palette (0)
  2599.         Channel 0 to Screen Offset 0
  2600.         Amal 0,"Loop: Let X=XM-128; Let Y=YM-45; Pause; Jump Loop"
  2601.         Amal On : Wait Key
  2602.  
  2603. This program allows you to scroll through the screen using the mouse.
  2604. Try moving the mouse in direct mode. For a further example of hardware
  2605. scrolling, see EXAMPLE 14.5
  2606.  
  2607.  
  2608. Changing the screen size                                                   199
  2609. ------------------------
  2610.  
  2611. CHANNEL n TO SCREEN SIZE s
  2612.  
  2613. This allows you to change the size of a screen using AMAL. s is the
  2614. number of the screen to be manipulated. Registers X and Y now control
  2615. the width and height of your screen respectively. They're similar to
  2616. the W and H parameters used by the SCREEN DISPLAY command. Example:
  2617.  
  2618.         Load Iff "AMOS_DATA:IFF/Magic_screen.IFF",0
  2619.         Channel 0 to Screen Size 0
  2620.         Screen display 0,,,320,1 : Rem set the screen size to 1
  2621.         A$=Loop: For R0=0 To 255 ; Let Y=R0 ; Next R0; "
  2622.         A$=A$+"For R0=0 To 254; Let Y=255-R0; Next R0; J Loop"
  2623.         Amal 0,A$ : Amal On : Direct
  2624.  
  2625.  
  2626. Rainbows
  2627. --------
  2628.  
  2629. CHANNEL n TO RAINBOW r
  2630.  
  2631. This option generates a rainbow effect within an AMAL program. As usual
  2632. n is the number of an animation channel from 0 to 63. r is an
  2633. identification number of your rainbow (0-3).
  2634.  
  2635.   X holds the current BASE of your rainbow. This is the first colour of
  2636. your rainbow palette to be displayed. Changing it will make the rainbow
  2637. appear to turn. Y contains the line on the screen at which the rainbow
  2638. effect will start. If you alter this value, the rainbow effect will
  2639. move up or down. All coordinates are measured in *hardware* format.
  2640.  
  2641.   Register A stores the height of your rainbow on the screen. See the
  2642. AMOS Basic RAINBOW command fore more details.
  2643.  
  2644.  
  2645. Advanced tehcniques
  2646. ===================
  2647.  
  2648. The AUTOTEST system
  2649. -------------------
  2650. Normally all AMAL programs are performed in strict order from start to
  2651. finish. Inevitably some commands such as Move and For...Next will take
  2652. several seconds to complete. Although this will be fine in the vast
  2653. majority of cases it may lead to significant delays in the running of
  2654. certain programs. Take the following simple program:
  2655.  
  2656.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  2657.         Sprite 8,130,50,1
  2658.         Amal 8,"Loop: Let R0=XM-X; Let R1=YM-Y; Move R0,R1,50; Jump Loop"
  2659.         Amal On : Direct
  2660.  
  2661. As you move the mouse, the sprite is supposed to follow it around on
  2662. the screen. However in practice the response time is quite sluggish,
  2663. because the new values of XM and YM are only entered after the sprite
  2664. movement has totally finished. Try moving the mouse in a circle. The
  2665. octopus is completely fooled!
  2666.  
  2667.   Autotest solves this problem by performing your tests at the start of
  2668. every VBL, before continuing with the current program. You tests now
  2669. occur at regular 1/50 intervals, leading to a practically instantanous
  2670. response!
  2671.  
  2672.  
  2673. Autotest commands                                                          200
  2674. -----------------
  2675. The syntax of Autotest is:
  2676.  
  2677. AUtotest (tests)
  2678. --
  2679.     "tests" can consist of any of the following AMAL commands.
  2680.  
  2681. Let reg=exp
  2682. -
  2683.     This is the standard AMAL Let instruction. It assigns the result
  2684.     of an expression to register "reg".
  2685.  
  2686. Jump label
  2687. -
  2688.     The Jump command jumps to another part of the current autotest.
  2689.     "label" is defined using the colon ":" and *MUST* lie inside the
  2690.     autotest brackets.
  2691.  
  2692. eXit
  2693.  -
  2694.     Leaves the autotest and re-enters the main program from the point
  2695.     it left off.
  2696.  
  2697. Wait
  2698. -
  2699.     Wait turns off the main AMAL program completely, and only executes
  2700.     the Autotest.
  2701.  
  2702. If
  2703. -
  2704.     In order to simplify the testing process inside an autotest routine
  2705.     there's a specially extended version of the AMAL If statement. This
  2706.     allows you to perform one of three actions depending on the result
  2707.     of the logical expression "exp".
  2708.  
  2709.     If exp Jump L   (Jumps to another part of the autotest)
  2710.     If exp Direct L (Chooses part of the prog to be executed after AU)     201
  2711.     If exp eXit     (Leaves autotest)
  2712.  
  2713. On
  2714. -
  2715.     Restarts the main program after a previous Wait instruction. This
  2716.     lets you wait for a specific event such as a mouse click without
  2717.     wasting processor time.
  2718.  
  2719. Direct label
  2720. -
  2721.     Direct changes the point at which the main program will be resumed
  2722.     after your test. AMAL will now jump to this point automatically at
  2723.     the next vertical blank period. Note that label *must* be defined
  2724.     outside the Autotest brackets.
  2725.  
  2726.  
  2727. Inside Autotest
  2728. ---------------
  2729. Here's the previous example rewritten using the Autotest feature
  2730.  
  2731.         Load "AMOS_DATA:Sprites/octopus.abk"
  2732.         Sprite 8,130,50,1 : Get Sprite Palette
  2733.         A$="AUtotest (If R0<>XM Jump Update"
  2734.         A$=A$+"If R1<>YM Jump Update else eXit"
  2735.         A$=A$+"Update: Let R0=XM; Let R1=YM; Direct M)" : Rem End of AU
  2736.         A$=A$+"M: Move R0-X,R1-Y,20 Wait;" : Rem Try changing 20 to
  2737.                                                  different values!
  2738.         Amal 8,A$ : Amal On
  2739.  
  2740. The sprite now smoothly follows your mouse, no matter how fast you move
  2741. it. The action of this program is as follows:
  2742.  
  2743.   Every 50th of a sec the mouse coordinates are tested using the XM and
  2744. YM functions. If they are unchanged since the last test, the Autotest
  2745. is aborted using the eXit command. The main program now resumes
  2746. precisely where it left off.
  2747.  
  2748.   However if the mouse has been moved, the autotest routine will
  2749. restart the main program again from the beginning (label M) using the
  2750. new coordinates in XM and YM respectively.
  2751.  
  2752.  
  2753. Timing considerations
  2754. ---------------------
  2755.  
  2756.  
  2757.                    UPDATE EVERY (save some time for
  2758.                          your Basic programs)
  2759. UPDATE EVERY n
  2760.  
  2761. Although most AMAL programs are performed practically instantaneously,
  2762. any objects they manipulate need to be explicity drawn on the Amiga's
  2763. screen.
  2764.  
  2765.   The amount of time required for this updating procedure is
  2766. unpredictable and can vary during the course or your program. This can
  2767. lead to an annoying jitter in the movement patterns of certain objects.
  2768.  
  2769.   The UPDATE EVERY command slows down the updating process so that even
  2770. the largest object can be redrawn during a single screen update. This
  2771. regulates the animation system and generates delightfully smooth
  2772. movement effects.
  2773.  
  2774.   n is the number of vertical blank periods between each screen update.
  2775. In practice you should start off with a value of two, and gradually
  2776. increase it until movement is smooth.
  2777.  
  2778.   One useful side effect of UPDATE EVERY, is to reserve more time for
  2779. Basic to execute your programs. With a judicious use of this
  2780. instruction, it's sometimes possible to speed up your programs by as
  2781. much as 30%, without destroying the smoothness of your animation
  2782. sequences.
  2783.  
  2784.  
  2785. Beating the 16 object limit                                                202
  2786. ---------------------------
  2787.  
  2788.  
  2789.               SYNCHRO (execute an AMAL program directly)
  2790.  
  2791. SYNCHRO [ON/OFF]
  2792.  
  2793. Normally AMOS Basic will allow you to execute up to 16 different AMAL
  2794. programs at a time. This limit is determined by the overall speed of
  2795. the Amiga's hardware. Each AMAL program takes its own slice of the
  2796. available processor time. So if you're using the standard interrupt
  2797. system, there's only enough time to execute around 16 separate
  2798. programs.
  2799.  
  2800.   The SYNCHRO command allows you to exceed this restriction by
  2801. executing your AMAL programs directly from Basic. Instead of using
  2802. interrupts, all AMAL programs are now run using a single call to the
  2803. SYNCHRO command. Since AMAL programs execute far faster than the
  2804. equivalent Basic routines, your animations will still be delightfully
  2805. smooth. But you will now able to decide when and where yur AMAL
  2806. routines will be performed in your program.
  2807.  
  2808.   One additional bonus is that you can now include collision detection
  2809. commands such as Bob Col or Sprite Col directly in your AMAL routines.
  2810. These are not available from the interrupt system as they make use of
  2811. the Amiga's blitter chip. This would be impossible using iterrupts.
  2812.  
  2813.   Before calling SYNCHRO you first need to turn off the interrupts with
  2814. SYNCHRO OFF. It's imporatnt to do this *before* defining your AMAL
  2815. programs, otherwise you won't be allowed to use channel numbers greater
  2816. than 15 without an error.
  2817.  
  2818.   Due of the sheer power of the animation system, it's nearly possible
  2819. to write entire arcade games completely in AMAL. This leaves your Basic
  2820. program with simple jobs such as managing the hi-score table and
  2821. loading your attack waves from the disc. The results will be
  2822. indistinguishable from pure machine code. A good example is Cartoon
  2823. Capers, the first commercial games release that's written entirely in
  2824. AMOS.
  2825.  
  2826.   A demonstration of SYNCHRO can be found in EXAMPLE 14.6.
  2827.  
  2828.  
  2829. STOS compatible animation commands
  2830. ----------------------------------
  2831. The original STOS Basic included a powerful animation system which
  2832. allowed you to move your sprites in quite complex patterns using
  2833. interrupts. At the time, these commands were hailed as a breakthrough.
  2834.  
  2835.   Although they've now been overshadowed by the AMAL system, they do       203
  2836. provide a simple introduction to animation on the Amiga. So AMOS
  2837. provides you with the entire STOS animation system as an extra bonus!
  2838.  
  2839.   If you're indenting to convert STOS programs to AMOS, you'll need to
  2840. note the following points:
  2841.  
  2842.   * Unlike STOS, the movement patterns in AMOS Basic can be assigned to
  2843.     any animation channel you like. The Move commands can therefore be
  2844.     used to move bobs, sprites or screens, using exactly the same
  2845.     techniques.
  2846.  
  2847.       As a default, all animation channels are assigned to the
  2848.     equivalent hardware sprites. In practice you may find it easier to
  2849.     substitute blitter objects as these are much close to the standard
  2850.     STOS Basic sprites. Add a sequence of CHANNEL commands to start of
  2851.     your program like so:
  2852.  
  2853.         Channel 1 to bob 1
  2854.         Channel 2 to bob 2
  2855.           :        :
  2856.  
  2857.     Don't forget to call DOUBLE BUFFER during your initialisation
  2858.     procedure, otherwise your bobs will flicker annoyingly when they're
  2859.     moved.
  2860.  
  2861.   * The same channel can be used for both STOS animations and AMAL
  2862.     programs. So it's easy to extend your programs once they've been
  2863.     succesfully converted into AMOS Basic. The order of execution is:
  2864.  
  2865.     AMAL
  2866.     MOVE X
  2867.     MOVE Y
  2868.     ANIM
  2869.  
  2870.  
  2871.                   MOVE X (move a sprite horizontally)
  2872.  
  2873. MOVE X n,m$
  2874.  
  2875. Defines a list of horizontal movements which will be subsequently
  2876. performed on animation channel number n.
  2877.  
  2878.   n can range from 0 to 15 and refers to an object you have previously
  2879. assigned using the CHANNEL command. m$ contains a sequence of
  2880. instructions which together determine both the speed and direction of
  2881. your object. These commands are enclosed between brackets and are
  2882. entered using the following format:
  2883.  
  2884.         (speed,step,count)
  2885.  
  2886. There's no limit to the number of commands you can include in a single
  2887. movement string, other than the amount of available memory.
  2888.  
  2889.   "speed" sets a delay in 50ths of a second between each successive
  2890. movement step. The speed can vary from 1 (very fast) to 32767
  2891. (incredibly slow).
  2892.  
  2893.   "step" specifies the number of pixels the object will be moved during
  2894. each operation. If the step is positive the sprite will move to the        204
  2895. right, and if it is negative it will move left.
  2896.  
  2897.   The apparent speed of the object depends on a combination of the
  2898. speed and step size. Large displacements coupled with a moderate speed
  2899. will move the object quickly but jerkily across the screen. Similarly a
  2900. small step size combined with a high speed will also move the object
  2901. rapidly, but the motion will be much smoother. The fastest speeds can
  2902. be obtained with a displacements of about 10 (or -10).
  2903.  
  2904.   "count" determines the number of times the movement will be repeated.
  2905. Possible values range from 0 to 32767. A count of 0 performs the
  2906. movement pattern indefinitely.
  2907.  
  2908.   In addition to the above commands, you can also add one of the
  2909. following directives at the end of your movement string.
  2910.  
  2911.   The most important of these extensios is the L instruction (for
  2912. loop), which jumps back to the start of the string and returns the
  2913. entire sequence again from the beginning. Example:
  2914.  
  2915.         Load "AMOS_DATA:Sprits/Octopus.abk" : Get Sprite Palette
  2916.         Sprite 1,130,100,1 : Rem Define Sprite 5
  2917.         Move X 1,"(1,5,60)(1,-5,60)L"
  2918.         Move On
  2919.  
  2920. The E option allows you to stop your object when it reaches a specific
  2921. point on the screen. Change the second to last line in the above
  2922. example to:
  2923.  
  2924.         Move X 1,"(1,5,30)E100"
  2925.  
  2926. Note that these end-points will only work if the x coordinate of the
  2927. object exactly reaches the value you originally designated in the
  2928. instruction. If this increment is badly chosen the object will leap
  2929. past the end-point in a single bound, and the test will fail. Example:
  2930.  
  2931.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  2932.         Channel 1 To Sprite 8 : Channel 2 To Sprite 10
  2933.         Print At(0,5)+"Looping OK"
  2934.         Sprite 8,130,100,1
  2935.         Move X 1,"(1,10,30)(1,-10,30)L"
  2936.         Move On
  2937.         Print At(0,10)+"Now press a key" : Wait Key
  2938.         Sprite 10,140,150,2
  2939.         Move X 2,"(1,15,20)L" : Move On 2
  2940.         Print At(0,15)+"Oh dear!" : Wait Key
  2941.  
  2942.  
  2943.  
  2944.                    MOVE Y (Move an vertical object)
  2945.  
  2946. MOVE Y n,m$
  2947.  
  2948. This instruction complements the MOVE X command by enabling you to move
  2949. an object vertically along the screen. As before, n refers to the
  2950. number of an animation sequence you've allocated using the CHANNEL
  2951. command, and ranges between 0 and 15.
  2952.  
  2953.   m$ holds a movement string in an identical format to MOVE X. Positive
  2954. displacements now correspond to a downward motion, and negative values
  2955. result in an upward movement. Examples:
  2956.  
  2957.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette          205
  2958.         Channel 1 to Sprite 8 : Sprite 8,130,10,1
  2959.         Move Y 1,"10(1,1,180)L"
  2960.         Channel 2 To Screen Display 0
  2961.         Move Y 2,"(1,4,25)(1,-4,25)
  2962.         Move On : Wait Key
  2963.  
  2964.  
  2965.  
  2966.                   MOVE ON/OFF (start/stop movements)
  2967.  
  2968. MOVE ON/OFF [n]
  2969.  
  2970. Before your movement patterns will be executed they need to be
  2971. activated using the MOVE ON command.
  2972.  
  2973.   "n" refers to the animation sequence you wish to start, and can range
  2974. from 0 to 15. If it's omitted then all your movements will be activated
  2975. simultaneously.
  2976.  
  2977.   MOVE OFF has exactly the opposite effect: It stops the relecant
  2978. movement sequences in their tracks.
  2979.  
  2980.  
  2981.  
  2982.           MOVE FREEZE (temporatily suspend sprite movements)
  2983.  
  2984. MOVE FREEZE [n]
  2985.  
  2986. The MOVE FREEZE command temporarily halts the movements of one or more
  2987. objects on the screen. These objects can be restarted again using
  2988. MOVE ON.
  2989.  
  2990.   "n" is completely optional and specifiew the number of a single
  2991. object to be suspended by this instruction.
  2992.  
  2993.  
  2994.  
  2995.                     =MOVON (return movement status)
  2996.  
  2997. x=MOVON(n)
  2998.  
  2999. MOVON checks whether a particular object is being moved by the MOVE X
  3000. and MOVE Y instructions. It returns -1 if object n is in motion, and 0
  3001. if it's stationary. Do not confuse this with the MOVE ON command. Also
  3002. note that MOVON searches for movement patterns generated using the MOVE
  3003. commands, so it will not detect any animations generated by AMAL.
  3004.  
  3005.  
  3006.  
  3007.                        ANIM (animate an object)
  3008.  
  3009. ANIM n,a$
  3010.  
  3011. Automatically flicks an object through a sequence of images creating a
  3012. smooth animation effect on the screen. These animations are performed
  3013. 50 times a second using interrupts, so they can be executed
  3014. simultaneously with your Basic programs.
  3015.  
  3016.   "n" is the number of the channel which specifies a sprite or bob to
  3017. be animated by this instruction.
  3018.  
  3019.   "a$" contains a series of instructions which define your animation
  3020. sequence. Each operation is split into two separate components enclosed
  3021. between round brackets.
  3022.  
  3023.   "image" is number of the image to be displayed during each frame of      206
  3024. the animation. "delay" specifies the length of time this image will be
  3025. hled on the screen (in 50ths of a sec.). Example:
  3026.  
  3027.         Load "AMOS_DATA:Sprites/Octopus.abk" : Get Sprite Palette
  3028.         Channel 1 to Sprite 8 : Sprite 8,200,100,1
  3029.         Anim 1,"(1,10)(2,10)(3,10)(4,10)"
  3030.         Anim On : Wait Key
  3031.  
  3032. Just as with the MOVE instruction, there's also an L directive which
  3033. enables you to repeat your animations continuously. So just change the
  3034. ANIM command in the previous example to the following:
  3035.  
  3036.         Anim 1,"(1,10)(2,10)(3,10)(4,10)L"
  3037.  
  3038.  
  3039.  
  3040.                    ANIM ON/OFF (start an animation)
  3041.  
  3042. ANIM ON/OFF [n]
  3043.  
  3044. ANIM ON activates a series of animations which have been previously
  3045. created using the ANIM command. n specifies the number of an individual
  3046. animation sequence to be initialised. If it's omitted, then all current
  3047. animation sequences will be started immediately.
  3048.  
  3049. ANIM OFF [n]
  3050.  
  3051. Halts one or more animation sequences started by ANIM ON.
  3052.  
  3053.  
  3054.  
  3055.                    ANIM FREEZE (freeze an animation)
  3056.  
  3057. ANIM FREEZE [n]
  3058.  
  3059. Temporarily freezes the current animation sequence on the screen. n
  3060. chooses a single animation sequence to be suspended. If it's not
  3061. included, all current animations will be affected. They can be
  3062. restarted at any time with a simple call to the ANIM ON instruction.
  3063.  
  3064.  
  3065.  
  3066.  
  3067.  
  3068.  
  3069.  
  3070.  
  3071.                         15: BACKGROUND GRAPHICS                            207
  3072.                     ------------------------------
  3073.  
  3074. Nowadays, it's not uncommon for an arcade game to contain hunderds of
  3075. different screens. With compaction, it's possible to crap a single 32
  3076. colour screen into about 30k of memory. So 100 screens would be the
  3077. equivalent of about 3 Megabytes of data. Imagine how difficult this
  3078. would be to fit into a standard A500!
  3079.  
  3080.   The classic way of avoiding this restriction, is to construct your
  3081. backgrounds out of a set of simple building blocks. Once these "tiles"
  3082. have been created, they can be placed on the screen in any order you
  3083. like. So the same set of tiles can be reused to generate a vast number
  3084. of potential screens. Each screen is now stored as a simple list of its
  3085. components, and requires a tiny fraction of the original memory.
  3086.  
  3087.   In order to exploit this system, you'll obviously need some way of
  3088. defining your various screen maps. As you might have guessed, we've
  3089. helpfully provided you with a powerful map definer accessory on the
  3090. AMOS program disc. Full details can be found in the accompanying
  3091. documentation file.
  3092.  
  3093.   AMOS Basic also includes a number of special instructions for drawing
  3094. your tiles on the screen. These make it easy to generate the fast
  3095. scrolling backgrounds that are the hallmark of a modern arcade game.
  3096.  
  3097.  
  3098. Icons
  3099. =====
  3100. Icons are separate images which have been especially designed for
  3101. producing your background screens. Once you've drawn an icon, it's
  3102. fixed permanently into place. So you can't move it to a new position
  3103. using the AMAL animation system.
  3104.  
  3105.   All icons are stored in their own AMOS memory bank (#2). This bank is
  3106. created using the Sprite definer accessory (on the AMOS Program disk),
  3107. and will be automatically saved along with your Basic programs.
  3108.  
  3109.   Like Bobs, Icons are displayed using the Amiga's amazing Blitter
  3110. chip. But since Icons are essentally static objects, they are usually
  3111. drawn in REPLACE mode. Your icons will therefore totally erase any
  3112. existing graphics at the current screen position.
  3113.  
  3114.  
  3115.  
  3116.                        PASTE ICON (draw an icon)
  3117.  
  3118. PASTE ICON x,y,n
  3119.  
  3120. Draws icon number n on the screen at GRAPHIC coordinates x,y. n is the
  3121. number of the icon which is to be displayed. This must have been
  3122. previously stored in the ICON bank.
  3123.  
  3124.   Icons can be freely positioned anywhere on the screen, subject to the
  3125. normal clipping rules. Example:
  3126.  
  3127.         Load "AMOS_DATA:Icons/Map_icons.abk"
  3128.         Screem Open 0,320,256,32,Lowres : Cls 0 : Get Icon Palette
  3129.         For X=1 To 11 : Paste Icon X*32,0,1 : Next X
  3130.         For Y=1 To 6 : Paste Icon 0,Y*32+11 : Paste Icon 288,Y*32,1
  3131.         Next Y
  3132.         For X=1 To 11 : Paste Icon X*32,223,1 : Next X
  3133.  
  3134. Note that if you're using double buffering, a copy of your icons will
  3135. be drawn into both the physical and logical screens. Since this is
  3136. rather slow, it's common practive to add a call to AUTOBACK 0 before
  3137. drawing your icons on the screen. This restricts straight to the
  3138. physical screen using SCREEN COPY, saving a considerable amount of
  3139. time.
  3140.  
  3141.   For a further example, see the MAPVIEW program on the AMOS DATA disc.
  3142. This displays a background screen you've created using the AMOS Map
  3143. Editor.
  3144.  
  3145.  
  3146.  
  3147.                        GET ICON (create an icon)                           208
  3148.  
  3149. GET ICON [s,] i,tx,ty TO bx,by
  3150.  
  3151. Captures an image from the screen and loads it into icon "i". If this
  3152. icon does not presently exist, it will be created for you in bank 2.
  3153. This bank will be automatically reserved by the system if required.
  3154.  
  3155.   i is the number of your icon, starting from 1. tx,ty to bx,by define
  3156. the rectangular zone which encloses the selected region.
  3157.  
  3158.   s determines the number of the screen which will be used as the
  3159. source of your image. If it's omitted, the image will be taken from the
  3160. current screen instead. Example:
  3161.  
  3162.         Erase 2
  3163.         F$=Fsel$("*.*","","Load a screen") : If F$="" Then Direct
  3164.         If Exist(f$) Then Load Iff f$,0 Else Direct
  3165.         SH=Screen Height : H=SH/32-1 : SW=Screen Width : W=SW/32-1
  3166.         For Y=0 to H
  3167.           For X=0 to W
  3168.             Get Icon X+Y*W+1,X*32,Y*32 To X*32+31,Y*32+31
  3169.           Next X
  3170.         Next Y
  3171.         Cls 0
  3172.         Do
  3173.           Paste Icon Rnd(Sw-1),Rnd(SH-1),Rnd/(H*W)+1
  3174.         Loop
  3175.  
  3176.  
  3177.  
  3178.                   GET ICON PALETTE (get icon colours)
  3179.  
  3180. GET ICON PALETTE
  3181.  
  3182. Grabs the colours of the icon images in bank 2, and loads them into the
  3183. current screen palette. This command is normally used to initialize the
  3184. screen after you'be loaded some icons from the disc. Example:
  3185.  
  3186.         Load "AMOS_DATA:Icons/Map_icons.abk"
  3187.         Get Icon Palette
  3188.         Paste Icon 100,100,1
  3189.  
  3190.  
  3191.  
  3192.                        DEL ICON (deletes icons)                            209
  3193.  
  3194. DEL ICON n[ TO m]
  3195.  
  3196. Deletes one or more icons from the icon bank. n is the number of the
  3197. first icon to be removed.
  3198.  
  3199.   m is the optional number of the last icon to be deleted in the list.
  3200. If it's included all the icons from first to last will be erased one
  3201. after another.
  3202.  
  3203.   When the final icon in a bank has been deleted, the entire bank will
  3204. be removed from memory.
  3205.  
  3206.  
  3207.  
  3208.             MAKE ICON MASK (set colour zero to transparent)
  3209.  
  3210. MAKE ICON MASK [n]
  3211.  
  3212. Normally, any icons you draw on the screen will completely replace the
  3213. existing background. The icon will seem to be displayed in a
  3214. rectangular box filled with colour zero.
  3215.  
  3216.   If you want to avoid this effect and overlay your icons directly over
  3217. the current graphics, you'll need to create a *mask* for your icons.
  3218. This informs AMOS that colour zero should be treated as transparent.
  3219.  
  3220.   n is the number of the icon to be affected. If it's omitted, a mask
  3221. will be defined for all icons in the bank. See EXAMPLE 15.1
  3222.  
  3223.  
  3224. Screen blocks
  3225. =============
  3226. AMOS Basic supplies you with a set of powerful BLOCK commands which
  3227. allow you to grab part of an image into memory and paste it anywhere on
  3228. the screen.
  3229.  
  3230.         These instructions are mainly used for holding temporary data,
  3231. since your blocks cannot be saved along with your Basic programs.
  3232.  
  3233.   Blocks are especially effective in the construction of dialogue
  3234. boxes, as they can be used to save the background areas before
  3235. displaying your new graphics.
  3236.  
  3237.   They can also be exploited in puzzle games like Split Personalities.
  3238. Each block can be loaded with a single section of your image. You can
  3239. then jumble your pictures by rearranging the blocks on the screen with
  3240. PUT BLOCK.
  3241.  
  3242.  
  3243.  
  3244.               GET BLOCK (grab a screen block into memory)
  3245.  
  3246. GET BLOCK n,tx,ty,w,h[,mask]
  3247.  
  3248. GET BLOCK grabs a rectangular area in block number n, starting at
  3249. coordinates tx,ty.
  3250.  
  3251.   n is the number of the block ranging from 1-65535. tx, ty set the
  3252. coordinates of the top left hand corner of your block. w,y hold the
  3253. width and height of the block respectively.
  3254.  
  3255.   "mask" is a flag which chooses whether a mask will be created for
  3256. your new block.
  3257.  
  3258.   mask=0        Replace mode. When the block is drawn on the screen,
  3259.                 it will totally destroy any graphics at that current
  3260.                 position.
  3261.   mask=1        Calculates a mask for the block. Colour zero will now
  3262.                 be treated as if it were transparent.
  3263.  
  3264.  
  3265.  
  3266.                 PUT BLOCK (copies a previously created                     210
  3267.                         block onto the screen)
  3268.  
  3269. PUT BLOCK n[,x,y]
  3270. PUT BLOCK n,x,y,planes[,minterms]
  3271.  
  3272. PUT BLOCK copies block number n to the current screen. x,y specify the
  3273. position of your new block on the screen. If they are omitted the block
  3274. will be redrawn at its original screen coordinates.
  3275.  
  3276.   Note that all drawing operations will be clipped to fit into the
  3277. current screen, starting from the nearest 16 pixel boundary.
  3278.  
  3279.   For a demostration of the BLOCK commands see the routine in EXAMPLE
  3280. 15.2. We've also provided experienced programmers with a couple of
  3281. optional extras. These are not needed for the vast majority of
  3282. applications, they're only required when you want to achieve weird
  3283. special effects on the screen!
  3284.  
  3285.   "planes" holds a bit-map which sets the range of colours which will
  3286. be drawn in your block. The Amiga's screen is divided up into segments
  3287. known as bit-planes. Each plane contains a single bit for every point
  3288. on the Amiga's screen. When the Amiga's hardware displays this point,
  3289. it combines the bits from each plane to calculate the required colour
  3290. number. Each bit in "planes" represents the status of a single
  3291. bit-plane. If it's set to one, then the selected plane will be drawn by
  3292. the instruction, otherwise it will be completely ignored. The first
  3293. plane is represented by bit zero, the second by bit one, etc.
  3294.  
  3295.   Usually, the block will be displayed in all the available bit-planes.
  3296. The corresponds to a bit-pattern of %111111
  3297.  
  3298.   "minterm" selects the blitter mode used to copy your block on the
  3299. screen. A full description of the possible drawing modes can be found
  3300. in the section on SCREEN COPY. The best way to loearn about these
  3301. options is to experiment!
  3302.  
  3303.  
  3304.  
  3305.                    DEL BLOCK (delete a screen block)
  3306.  
  3307. DEL BLOCK n
  3308.  
  3309. Deletes one or more blocks and restores the memory used to AMOS Basic.
  3310.  
  3311. DEL BLOCK       Erases *all* current blocks
  3312. DEL BLOCK n     Deletes block number n.
  3313.  
  3314.  
  3315.  
  3316.              GET CBLOCK (save and compact a screen image)                  211
  3317.  
  3318. GET BLOCK n,x,y,sx,sy
  3319.  
  3320. The GET BLOCK command saves and compacts a rectangular area of the
  3321. screen. The compaction system used by this command has been especially
  3322. optimized for speed. So it's nowhere near as efficient as the dedicated
  3323. AMOS compression routines provided by the PACK or SPACK instructions.
  3324.  
  3325.   CBLOCKS are often used to grab the area underneath your dialogue
  3326. boxes. After the dialogue has been completed, the screen can quickly
  3327. restored back to its original state. See EXAMPLE 15.3.
  3328.  
  3329.   n specifies the number of your block and can range between 1-65535.
  3330.  
  3331.   x,y are the top left coordinates. The x coordinate is rouded to the
  3332. nearest multiple of 8.
  3333.  
  3334.   w,h hold the dimensios of the area to be saved. The width is always
  3335. rounded to an exact multiple of 8.
  3336.  
  3337.                      PUT CBLOCK (displays a block
  3338.                          created using CBLOCK)
  3339.  
  3340. PUT CBLOCK n [,x,y]
  3341.  
  3342. Places block n on the current screen at coordinates x,y. If the target
  3343. coordinates are omitted, the block will be redrawn at its original
  3344. screen position. Also note that x is automatically rounded to the
  3345. nearest eight pixel boundary.
  3346.  
  3347.                   DEL CBLOCK (deletes a screen block
  3348.                        defined with GET CBLOCK)
  3349.  
  3350. DEL CBLOCK [n]
  3351.  
  3352. Erases all blocks from memory. If n is present only block n will be
  3353. deleted.
  3354.